Issue Details (XML | Word | Printable)

Key: OPENEJB-756
Type: Improvement Improvement
Status: Closed Closed
Resolution: Fixed
Priority: Minor Minor
Assignee: Dain Sundstrom
Reporter: scott selikoff
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
OpenEJB

Allow CMP2 ejbSelect returning void for UPDATE and DELETE queries

Created: 20/Feb/08 08:56 PM   Updated: 01/Mar/08 07:32 PM
Return to search
Component/s: cmp2
Affects Version/s: 3.0-beta-2
Fix Version/s: 3.0

Time Tracking:
Original Estimate: 4h
Original Estimate - 4h
Remaining Estimate: 4h
Remaining Estimate - 4h
Time Spent: Not Specified
Remaining Estimate - 4h

Environment: N/A

Resolution Date: 01/Mar/08 07:32 PM


 Description  « Hide
The method Cmp2Generator.createSelectMethod() does not support "none" return type. If an ejb.select method is created with result-type-mapping="none", then the return type will return type will get converted to void. This will throw a non-descriptive NullPointerException on line 778, since the return of Cmp2Generator.Convert.getConversion() will be null.

Recommendations:

FIX #1: Better error message than NullPointerException

A better error message would be appreciated here as is seen in the fromObjectTo() method such as:

public static void fromObjectTo(MethodVisitor mv, Class to) {
            if (to.equals(Object.class)) {
                // direct assignment will work
            } else if (!to.isPrimitive()) {
                mv.visitTypeInsn(CHECKCAST, Type.getInternalName(to));
            } else {
                Convert conversion = getConversion(to);
                if (conversion == null) throw new NullPointerException("unsupported conversion for EJB select return type " + from.getName());
                conversion.objectToPrimitive(mv);
            }
        }

FIX #2: Add void as a supported type. Also, verify doing so would not be a spec violation.


TO REPRODUCE: Create a bean method such as the following:

/**
* @ejb.transaction
* type="Mandatory"
* @ejb.select
* query="DELETE FROM someSCHEMA as a WHERE a.someId=?1"
* result-type-mapping="none"
*
* @param someId
*/
public abstract void ejbSelectRemoveById(java.lang.Integer someId) throws FinderException;

Disclaimer: I take no responsibility in the code sample... I was the one charged with debugging it when upgrading from Geronimo 1 to 2.1, not writing it. I understand there are better ways to do this.

 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
scott selikoff made changes - 20/Feb/08 09:18 PM
Field Original Value New Value
Description The method Cmp2Generator.createSelectMethod() does not support "none" return type. If an ejb.select method is created with result-type-mapping="mapping", then the return type will return type will get converted to void. This will throw a non-descriptive NullPointerException on line 778, since the return of Cmp2Generator.Convert.getConversion() will be null.

Recommendations:

Fix #1: Better error message than NullPointerException

A better error message would be appreciated here as is seen in the fromObjectTo() method such as:

public static void fromObjectTo(MethodVisitor mv, Class to) {
            if (to.equals(Object.class)) {
                // direct assignment will work
            } else if (!to.isPrimitive()) {
                mv.visitTypeInsn(CHECKCAST, Type.getInternalName(to));
            } else {
                Convert conversion = getConversion(to);
                if (conversion == null) throw new NullPointerException("unsupported conversion for EJB select return type " + from.getName());
                conversion.objectToPrimitive(mv);
            }
        }

Fix #2: Add void as a supported type. Also, verify doing so would not be a spec violation.
The method Cmp2Generator.createSelectMethod() does not support "none" return type. If an ejb.select method is created with result-type-mapping="none", then the return type will return type will get converted to void. This will throw a non-descriptive NullPointerException on line 778, since the return of Cmp2Generator.Convert.getConversion() will be null.

Recommendations:

Fix #1: Better error message than NullPointerException

A better error message would be appreciated here as is seen in the fromObjectTo() method such as:

public static void fromObjectTo(MethodVisitor mv, Class to) {
            if (to.equals(Object.class)) {
                // direct assignment will work
            } else if (!to.isPrimitive()) {
                mv.visitTypeInsn(CHECKCAST, Type.getInternalName(to));
            } else {
                Convert conversion = getConversion(to);
                if (conversion == null) throw new NullPointerException("unsupported conversion for EJB select return type " + from.getName());
                conversion.objectToPrimitive(mv);
            }
        }

Fix #2: Add void as a supported type. Also, verify doing so would not be a spec violation.
scott selikoff made changes - 20/Feb/08 09:25 PM
Description The method Cmp2Generator.createSelectMethod() does not support "none" return type. If an ejb.select method is created with result-type-mapping="none", then the return type will return type will get converted to void. This will throw a non-descriptive NullPointerException on line 778, since the return of Cmp2Generator.Convert.getConversion() will be null.

Recommendations:

Fix #1: Better error message than NullPointerException

A better error message would be appreciated here as is seen in the fromObjectTo() method such as:

public static void fromObjectTo(MethodVisitor mv, Class to) {
            if (to.equals(Object.class)) {
                // direct assignment will work
            } else if (!to.isPrimitive()) {
                mv.visitTypeInsn(CHECKCAST, Type.getInternalName(to));
            } else {
                Convert conversion = getConversion(to);
                if (conversion == null) throw new NullPointerException("unsupported conversion for EJB select return type " + from.getName());
                conversion.objectToPrimitive(mv);
            }
        }

Fix #2: Add void as a supported type. Also, verify doing so would not be a spec violation.
The method Cmp2Generator.createSelectMethod() does not support "none" return type. If an ejb.select method is created with result-type-mapping="none", then the return type will return type will get converted to void. This will throw a non-descriptive NullPointerException on line 778, since the return of Cmp2Generator.Convert.getConversion() will be null.

Recommendations:

FIX #1: Better error message than NullPointerException

A better error message would be appreciated here as is seen in the fromObjectTo() method such as:

public static void fromObjectTo(MethodVisitor mv, Class to) {
            if (to.equals(Object.class)) {
                // direct assignment will work
            } else if (!to.isPrimitive()) {
                mv.visitTypeInsn(CHECKCAST, Type.getInternalName(to));
            } else {
                Convert conversion = getConversion(to);
                if (conversion == null) throw new NullPointerException("unsupported conversion for EJB select return type " + from.getName());
                conversion.objectToPrimitive(mv);
            }
        }

FIX #2: Add void as a supported type. Also, verify doing so would not be a spec violation.


TO REPRODUCE: Create a bean method such as the following:

/**
* @ejb.transaction
* type="Mandatory"
* @ejb.select
* query="DELETE FROM someSCHEMA as a WHERE a.someId=?1"
* result-type-mapping="none"
*
* @param someId
*/
public abstract void ejbSelectRemoveById(java.lang.Integer someId) throws FinderException;

Disclaimer: I take responsibility in the code sample... I was the one charged with debugging it, not writing it. I understand there are better ways to do this.
scott selikoff made changes - 20/Feb/08 09:25 PM
Description The method Cmp2Generator.createSelectMethod() does not support "none" return type. If an ejb.select method is created with result-type-mapping="none", then the return type will return type will get converted to void. This will throw a non-descriptive NullPointerException on line 778, since the return of Cmp2Generator.Convert.getConversion() will be null.

Recommendations:

FIX #1: Better error message than NullPointerException

A better error message would be appreciated here as is seen in the fromObjectTo() method such as:

public static void fromObjectTo(MethodVisitor mv, Class to) {
            if (to.equals(Object.class)) {
                // direct assignment will work
            } else if (!to.isPrimitive()) {
                mv.visitTypeInsn(CHECKCAST, Type.getInternalName(to));
            } else {
                Convert conversion = getConversion(to);
                if (conversion == null) throw new NullPointerException("unsupported conversion for EJB select return type " + from.getName());
                conversion.objectToPrimitive(mv);
            }
        }

FIX #2: Add void as a supported type. Also, verify doing so would not be a spec violation.


TO REPRODUCE: Create a bean method such as the following:

/**
* @ejb.transaction
* type="Mandatory"
* @ejb.select
* query="DELETE FROM someSCHEMA as a WHERE a.someId=?1"
* result-type-mapping="none"
*
* @param someId
*/
public abstract void ejbSelectRemoveById(java.lang.Integer someId) throws FinderException;

Disclaimer: I take responsibility in the code sample... I was the one charged with debugging it, not writing it. I understand there are better ways to do this.
The method Cmp2Generator.createSelectMethod() does not support "none" return type. If an ejb.select method is created with result-type-mapping="none", then the return type will return type will get converted to void. This will throw a non-descriptive NullPointerException on line 778, since the return of Cmp2Generator.Convert.getConversion() will be null.

Recommendations:

FIX #1: Better error message than NullPointerException

A better error message would be appreciated here as is seen in the fromObjectTo() method such as:

public static void fromObjectTo(MethodVisitor mv, Class to) {
            if (to.equals(Object.class)) {
                // direct assignment will work
            } else if (!to.isPrimitive()) {
                mv.visitTypeInsn(CHECKCAST, Type.getInternalName(to));
            } else {
                Convert conversion = getConversion(to);
                if (conversion == null) throw new NullPointerException("unsupported conversion for EJB select return type " + from.getName());
                conversion.objectToPrimitive(mv);
            }
        }

FIX #2: Add void as a supported type. Also, verify doing so would not be a spec violation.


TO REPRODUCE: Create a bean method such as the following:

/**
* @ejb.transaction
* type="Mandatory"
* @ejb.select
* query="DELETE FROM someSCHEMA as a WHERE a.someId=?1"
* result-type-mapping="none"
*
* @param someId
*/
public abstract void ejbSelectRemoveById(java.lang.Integer someId) throws FinderException;

Disclaimer: I take no responsibility in the code sample... I was the one charged with debugging it when upgrading from Geronimo 1 to 2.1, not writing it. I understand there are better ways to do this.
David Blevins made changes - 24/Feb/08 09:09 PM
Fix Version/s 3.0 [ 12312805 ]
Fix Version/s 3.0-beta-2 [ 12312804 ]
Repository Revision Date User Message
ASF #632648 Sat Mar 01 19:27:51 UTC 2008 dain OPENEJB-756 Allow CMP2 ejbSelect returning void for UPDATE and DELETE queries
Files Changed
MODIFY /openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpEngine.java
MODIFY /openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/EjbSelect.java
MODIFY /openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Generator.java
MODIFY /openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/entity/cmp2/Cmp2EjbHomeTests.java
MODIFY /openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmp/BasicCmp2Bean.java
MODIFY /openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java
MODIFY /openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmp/BasicCmpBean.java
MODIFY /openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmp/BasicCmpHome.java
MODIFY /openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/resources/META-INF/ejb-jar.xml
MODIFY /openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java
MODIFY /openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/entity/cmp/CmpAllowedOperationsTests.java
MODIFY /openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmp/AllowedOperationsCmpBean.java
MODIFY /openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmp/AllowedOperationsCmp2Bean.java

Dain Sundstrom added a comment - 01/Mar/08 07:32 PM
I will implement option 2. When an ejbSelect method returns void, the CMP engine will assume that the query is an UPDATE or DELETE query, and will execute javax.persistence.Query.executeUpdate(). Unfortunately, there is no way to propagate the return value from the executeUpdate method since the ejbSelect method returns void. This feature is outside of the EJB spec and therefore will most likely not work in other application servers.

Dain Sundstrom made changes - 01/Mar/08 07:32 PM
Assignee Dain Sundstrom [ dain ]
Summary CMP2 Select Generation does not include VOID return type Allow CMP2 ejbSelect returning void for UPDATE and DELETE queries
Issue Type Bug [ 1 ] Improvement [ 4 ]
Dain Sundstrom added a comment - 01/Mar/08 07:32 PM
Committed revision 632648.

Dain Sundstrom made changes - 01/Mar/08 07:32 PM
Resolution Fixed [ 1 ]
Status Open [ 1 ] Closed [ 6 ]