Re: CAY-1345) enum construction requires string name of enum

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Wed Dec 23 2009 - 04:17:09 EST

  • Next message: Andrus Adamchik: "Re: 3.0 tutorial"

    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 <ar..aniatis.org>
    >
    >> 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 {
    >>>
    >>> ..verride
    >>> ..uppressWarnings("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



    This archive was generated by hypermail 2.0.0 : Wed Dec 23 2009 - 04:17:46 EST