Yep, the fix looks good to me (and this *is* a bug in 3.0). One note:

   type.isAssignableFrom(ExtendedEnumeration.class)

should be

   ExtendedEnumeration.class.isAssignableFrom(type)

Andrus

On Dec 23, 2009, at 8:59 AM, Andrey Razumovsky wrote:

Looks fine. It's a regression in B1 (caused by CAY-1261), and it'll be great
if you committed the fix. setProperty() should work correct for
ExtendedEnums as well

2009/12/23 Aristedes Maniatis <[email protected]>

What do people think of this as a solution? And what about getting that into 3.0? This really is a bug in 3.0 I think, since the whole concept of
the interface ExtendedEnumeration is flawed at the moment.

I haven't done any testing of this yet, but Marcin was going to see if he could write a few unit tests and also test it inside our own application.

Ari Maniatis


On 22/12/09 4:22 PM, Ari Maniatis (JIRA) wrote:


   [
https://issues.apache.org/jira/browse/CAY-1345?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12793501 #action_12793501]

Ari Maniatis commented on CAY-1345:
-----------------------------------

I believe the problem here is summarised as:

* Our enum converter is able to convert an enum to any database value with "Object getDatabaseValue()" in the ExtendedEnumeration class. But it can only convert back again to an object if the database value is the *name* of
the enum.

Here is a potential fix:



class EnumConverter extends Converter {

   @Override
   @SuppressWarnings("unchecked")
   Object convert(Object object, Class type) {

       if (object == null) {
           return null;
       }

       try {
           if (type.isAssignableFrom(ExtendedEnumeration.class)) {
               for (ExtendedEnumeration en : (ExtendedEnumeration[])
type.getMethod(
                       "values").invoke(null)) {
                   if (en.getDatabaseValue().equals(object))
                       return en;
               }
               return null;
           }
       }
       catch (Exception e1) {
           return null;
       }

       return Enum.valueOf(type, object.toString());
   }
}

enum as a class designator column (inheritance)
-----------------------------------------------

               Key: CAY-1345
               URL: https://issues.apache.org/jira/browse/CAY-1345
           Project: Cayenne
        Issue Type: Bug
        Components: Cayenne Core Library
  Affects Versions: 3.0M6
          Reporter: Marcin Skladaniec
           Fix For: 3.0 beta 2


In our setup we are using an int column as a column designator (called
'type').
this column is then mapped into an enum (called ProductType).
when creating new objects following stacktrace is created:
[java] org.apache.cayenne.CayenneRuntimeException: [v.3.0B1 Nov 03
2009 19:16:06] Error setting property segment 'type' in path 'type'
    [java]    at
org .apache .cayenne.reflect.PropertyUtils.setProperty(PropertyUtils.java:169)
    [java]    at
org .apache.cayenne.exp.parser.ASTObjPath.injectValue(ASTObjPath.java: 97)
    [java]    at
org.apache.cayenne.exp.parser.ASTEqual.injectValue(ASTEqual.java: 162)
    [java]    at
org .apache.cayenne.BaseContext.injectInitialValue(BaseContext.java: 407)
    [java]    at
org .apache .cayenne.CayenneContext.registerNewObject(CayenneContext.java:540)
    [java]    at
org.apache.cayenne.CayenneContext.newObject(CayenneContext.java: 349)
    [java]    at
ish.oncourse.cayenne.CayenneContext.newObject(CayenneContext.java: 279)
    [java]    at
ish.oncourse.cayenne.CayenneContext.newObject(CayenneContext.java: 32)
    [java]    at
ish .oncourse .controller .ControllerFactory.createEditController(ControllerFactory.java:112)
    [java]    at
ish .oncourse .controller .ControllerFactory.createEditController(ControllerFactory.java:93)
    [java]    at
ish .oncourse .controller .ControllerFactory.createEditController(ControllerFactory.java:134)
    [java]    at
ish .oncourse .controller .entity .ProductListController.newRecord(ProductListController.java:76)
    [java]    at
ish.oncourse.controller.ListController $3.execute(ListController.java:1312)
    [java]    at
ish .oncourse .actions.PermissibleAction.actionPerformed(PermissibleAction.java: 101)
    [java]    at
ish.view.components.Button.fireActionPerformed(Button.java:189)
    [java]    at
ish.view.components.Button.actionPerformed(Button.java:166)
    [java]    at
javax .swing.AbstractButton.fireActionPerformed(AbstractButton.java:2028)
    [java]    at
javax.swing.AbstractButton $Handler.actionPerformed(AbstractButton.java:2351)
    [java]    at
javax .swing .DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java: 387)
    [java]    at
javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java: 242)
    [java]    at
javax .swing .plaf .basic.BasicButtonListener.mouseReleased(BasicButtonListener.java: 236)
    [java]    at
java .awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java: 272)
    [java]    at
java.awt.Component.processMouseEvent(Component.java:6348)
    [java]    at
javax.swing.JComponent.processMouseEvent(JComponent.java:3255)
[java] at java.awt.Component.processEvent(Component.java: 6113) [java] at java.awt.Container.processEvent(Container.java: 2085)
    [java]    at
java.awt.Component.dispatchEventImpl(Component.java:4714)
    [java]    at
java.awt.Container.dispatchEventImpl(Container.java:2143)
[java] at java.awt.Component.dispatchEvent(Component.java: 4544)
    [java]    at
java.awt.LightweightDispatcher.retargetMouseEvent(Container.java: 4618)
    [java]    at
java.awt.LightweightDispatcher.processMouseEvent(Container.java: 4282)
    [java]    at
java.awt.LightweightDispatcher.dispatchEvent(Container.java:4212)
    [java]    at
java.awt.Container.dispatchEventImpl(Container.java:2129)
[java] at java.awt.Window.dispatchEventImpl(Window.java: 2475) [java] at java.awt.Component.dispatchEvent(Component.java: 4544) [java] at java.awt.EventQueue.dispatchEvent(EventQueue.java:635)
    [java]    at
java .awt .EventDispatchThread .pumpOneEventForFilters(EventDispatchThread.java:296)
    [java]    at
java .awt .EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java: 211)
    [java]    at
java .awt .EventDispatchThread .pumpEventsForHierarchy(EventDispatchThread.java:201)
    [java]    at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java: 196)
    [java]    at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java: 188)
    [java]    at
java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
[java] Caused by: java.lang.IllegalArgumentException: No enum const
class ish.oncourse.cayenne.ProductType.2
    [java]    at java.lang.Enum.valueOf(Enum.java:196)
    [java]    at
org .apache.cayenne.reflect.EnumConverter.convert(EnumConverter.java: 35)
    [java]    at
org .apache .cayenne .reflect.PropertyUtils.setSimpleProperty(PropertyUtils.java:229)
    [java]    at
org .apache .cayenne.reflect.PropertyUtils.setProperty(PropertyUtils.java:166)
    [java]    ... 41 more
there is a simple workaround, invoking setType(ProductType.MEMBERSHIP) on the new object fixes the problem. Yet it will be nice if the underlying
cayenne mechanism worked with enums/int columns.



--

-------------------------->
Aristedes Maniatis
GPG fingerprint CBFB 84B4 738D 4E87 5E5C  5EFA EF6A 7D2E 3E49 102A




--
Andrey

Reply via email to