-
1. Re: Further extending an EntityHome
matt.drees Sep 22, 2007 7:17 PM (in response to damianharvey)Well, you could manually specify the entity class, eg
@Override public Class<Booking> getEntityClass() { return Booking.class; }
Or maybe you could do something like... getClass.getSuperclass().getGenericSuperclass() ...(then same as in Home.java)
if you don't want to hardcode it. -
2. Re: Further extending an EntityHome
wise_guybg Sep 23, 2007 3:30 AM (in response to damianharvey)Have you not put different @Name annotations?
Where exactly do you get the error? -
3. Re: Further extending an EntityHome
damianharvey Sep 23, 2007 1:50 PM (in response to damianharvey)@Matt: I'll try that and let you know. Much appreciated.
@Wise_guy: As mentioned the error is in the Home class. There is an explicit check that the parent class is parameterized with a generic type. @Name annotations are different as they are to be ued on different pages.
Thanks,
Damian. -
4. Re: Further extending an EntityHome
damianharvey Sep 23, 2007 4:38 PM (in response to damianharvey)Bingo. Cheers Matt. Worked a treat. Your first suggestion worked first time (always nice).
Does anyone know what behaviour that the block of code in the Home object is trying to avoid? ie: why not just take the class rather than throw the exception?
Thanks,
Damian. -
5. Re: Further extending an EntityHome
matt.drees Sep 23, 2007 5:35 PM (in response to damianharvey)"damianharvey" wrote:
Bingo. Cheers Matt. Worked a treat. Your first suggestion worked first time (always nice).
Cool"damianharvey" wrote:
Does anyone know what behaviour that the block of code in the Home object is trying to avoid? ie: why not just take the class rather than throw the exception?
I think perhaps you misread that code. I'll post it here for reference:public Class<E> getEntityClass() { if (entityClass==null) { Type type = getClass().getGenericSuperclass(); if (type instanceof ParameterizedType) { ParameterizedType paramType = (ParameterizedType) type; entityClass = (Class<E>) paramType.getActualTypeArguments()[0]; } else { throw new IllegalArgumentException("Could not guess entity class by reflection"); } } return entityClass; }
EntityHome needs to know what your entity's class is, so that it can create a new instance when needed. What it does is check to see if you've set an entity class (which is usually, I imagine, only done if this Home was created by xml in components.xml). If you haven't, it tries to guess the class by looking at the type parameter of the home instance's superclass.
In your case, the superclass wasn't EntityHome, but BookingHome, which has no type parameter. So, it couldn't get the class and threw an exception.
Make sense? -
6. Re: Further extending an EntityHome
damianharvey Sep 24, 2007 6:23 AM (in response to damianharvey)Had to add a line to the suggested code otherwise a NPE was thrown on persist:
@Override public Class<Booking> getEntityClass() { super.setEntityClass(Booking.class); return Booking.class; }
Cheers,
Damian. -
7. Re: Further extending an EntityHome
mustaghattack Sep 24, 2007 7:34 AM (in response to damianharvey)You may have to parameterize your BookingHome : try
public class BookingHome< B extends Booking > extends EntityHome< B > {
and thenpublic class BulkBookingHome extends BookingHome<BulkBooking> {
-
8. Re: Further extending an EntityHome
damianharvey Sep 24, 2007 9:10 AM (in response to damianharvey)Thanks Mushtag but it's working fine with Matt's solution. Also BulkBooking isn't an Entity. BulkBookingHome is just a way of creating a Booking entity using some different logic.
Cheers,
Damian. -
9. Re: Further extending an EntityHome
pmuir Sep 24, 2007 4:23 PM (in response to damianharvey)Damian, please create a JIRA issue with the NPE in it and a link to this topic. We need to fix it.
-
10. Re: Further extending an EntityHome
damianharvey Sep 25, 2007 4:03 AM (in response to damianharvey)Pete,
I don't think it's an issue. The NPE was only caused by the fact that I had overriden getEntityClass() but hadn't set the value of the entityClass field.
Cheers,
Damian. -
11. Re: Further extending an EntityHome
mustaghattack Sep 25, 2007 5:03 AM (in response to damianharvey)Hi, about the EntityHome class I think it would be better to just pass the entity class as a parameter for the constructor, or at least to have a parameterized constructor.
I've done a quick performance test to see the reflection overhead :
with a Sun 1.6 JVM it's > 30.package test.java; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public class GuessParameterizePerformanceTest { public static class GuessParam< E > { private Class< E > entityClass; public GuessParam() { getEntityClass(); } public Class<E> getEntityClass() { if (entityClass==null) { Type type = getClass().getGenericSuperclass(); if (type instanceof ParameterizedType) { ParameterizedType paramType = (ParameterizedType) type; entityClass = (Class<E>) paramType.getActualTypeArguments()[0]; } else { throw new IllegalArgumentException("Could not guess entity class by reflection"); } } return entityClass; } } public static class DontGuessParam< E > { private Class< E > entityClass; public DontGuessParam( Class< E > cls ) { this.entityClass = cls; getEntityClass(); } public Class< E > getEntityClass() { return entityClass; } } public static class GuessParamChild extends GuessParam< String > { } public static class DontGuessParamChild extends DontGuessParam< String > { public DontGuessParamChild() { super( String.class ); } } public static void main(String[] args) { float avgGuess = 0, avgDontGuess = 0; float nbLoop = 5, nbInstanciation = 1000000; long time; for( long i = 0; i < nbLoop; i ++ ) { time = System.currentTimeMillis(); for( long j = 0; j < nbInstanciation; j ++ ) { GuessParamChild guess = new GuessParamChild(); } avgGuess += System.currentTimeMillis() - time; time = System.currentTimeMillis(); for( long j = 0; j < nbInstanciation; j ++ ) { DontGuessParamChild dontGuess = new DontGuessParamChild(); } avgDontGuess += System.currentTimeMillis() - time; } System.out.println("avgGuess = " + (avgGuess / nbLoop)); System.out.println("avgDontGuess = " + (avgDontGuess / nbLoop)); System.out.println( "Guess overhead : " + ( avgGuess - avgDontGuess ) / avgDontGuess ); } }
-
12. Re: Further extending an EntityHome
matt.drees Sep 25, 2007 12:06 PM (in response to damianharvey)"damianharvey" wrote:
I don't think it's an issue. The NPE was only caused by the fact that I had overriden getEntityClass() but hadn't set the value of the entityClass field.
Actually, I agree with Pete. If the contract of EntityHome requires getEntityClass() to be overridable (and it is, from what I gather), then it should always reference the getter, not the field. -
13. Re: Further extending an EntityHome
matt.drees Sep 25, 2007 12:13 PM (in response to damianharvey)"mustaghattack" wrote:
Hi, about the EntityHome class I think it would be better to just pass the entity class as a parameter for the constructor, or at least to have a parameterized constructor.
Seam instantiates (javabean) components with a no-arg constructor, so this won't help, unless you yourself instantiate an entityHome using "new", which you shouldn't ever be doing. -
14. Re: Further extending an EntityHome
damianharvey Sep 25, 2007 12:23 PM (in response to damianharvey)Fair call Matt. I can see your point. It's a resonably trivial fix as only updatedMessage(), deletedMessage() and createdMessage() refer to entityClass rather than getEntityClass.
http://jira.jboss.org/jira/browse/JBSEAM-1969
Cheers,
Damian.