Upgrading from Ebean 3.2.5 - NPE and null IDs

59 views
Skip to first unread message

Christie

unread,
Mar 18, 2016, 6:17:48 PM3/18/16
to Ebean ORM
I am trying to upgrade an old project from Ebean 3.2.5 to 6.18.1.  I have gotten the webapp to run with the upgraded Ebean libraries now, and some of it appears to be working properly, but I've run into some problems:

java.lang.NullPointerException
    at com.avaje.ebeaninternal.server.properties.EnhanceBeanPropertyInfo$Getter.get(EnhanceBeanPropertyInfo.java:67)
    at com.avaje.ebeaninternal.server.deploy.BeanProperty.getValue(BeanProperty.java:724)
    at com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany.addBeanToCollectionWithCreate(BeanPropertyAssocMany.java:186)  [detailBean is an ItemStore object, parentBean is null]
    at com.avaje.ebeaninternal.server.query.SqlTreeNodeManyRoot.load(SqlTreeNodeManyRoot.java:27) [parentBean is an Item object, detailBean is an ItemStore, contextParent is null]
    at com.avaje.ebeaninternal.server.query.SqlTreeNodeBean.load(SqlTreeNodeBean.java:298)
    at com.avaje.ebeaninternal.server.query.CQuery.readNextBean(CQuery.java:437)
    at com.avaje.ebeaninternal.server.query.CQuery.hasNext(CQuery.java:512)
    at com.avaje.ebeaninternal.server.query.CQuery.readCollection(CQuery.java:543)
    at com.avaje.ebeaninternal.server.query.CQueryEngine.findMany(CQueryEngine.java:302)

The code it's trying to run is:
String query = "find item join itemStores join itemStores.itemPrices where item.id=:id and itemStores.id is not null and available = true";
return Ebean.createQuery(Item.class, query).setParameter("id", item.getId()).setDistinct(true).findList();


The relationship looks like this:

In ItemStore.java:
@ManyToOne(targetEntity = Item.class, fetch = FetchType.EAGER)
private Item itemPackage;


In Item.java:
@OneToMany(targetEntity = ItemStore.class, fetch = FetchType.EAGER, mappedBy = "itemPackage", cascade = CascadeType.ALL)
private List<ItemStore> itemStores = new ArrayList<ItemStore>();


Both entities are annotated with @Entity and extend BaseEntity, which starts off:

@MappedSuperclass
public abstract class BaseEntity implements Serializable{
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
protected Long id;

@Version
protected Integer version;


Another part of the system runs

Query<Foo> q = Ebean.createQuery(Foo.class, query.toString());//query is something like "find foo where ......"
List<Foo> objects = q.findList();


and when I iterate right away through the list the query returns and print out the id field, they're all null.  But the id field is not null in other parts of the system.

I scanned the release notes for breaking changes that looked relevant but didn't see anything.  Any ideas?

Thanks,

Christie

Rob Bygrave

unread,
Mar 18, 2016, 6:25:52 PM3/18/16
to ebean@googlegroups

What version of the enhancer are you using? The latest is 4.9.2.

Ebean 3.x used a different enhancement and any Ebean version greater than 4.x needs the later 4.x enhancement.

Cheers, Rob.

--

---
You received this message because you are subscribed to the Google Groups "Ebean ORM" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ebean+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Christie

unread,
Mar 18, 2016, 6:27:19 PM3/18/16
to Ebean ORM
I'm using 4.8.1, so not too far behind.

Rob Bygrave

unread,
Mar 18, 2016, 6:34:06 PM3/18/16
to ebean@googlegroups

The problem I suspect is with the query syntax ... Using 'join' which got deprecated at some point and replaced with 'fetch'.

So you can try replacing 'join' with 'fetch'. Alternatively use the criteria API (rather than string query language).

Christie

unread,
Mar 18, 2016, 6:43:30 PM3/18/16
to Ebean ORM
Hmm, same stack trace when I replaced "join" with "fetch."  The whole project is using the string query language so I'd rather not rewrite all the queries if I can get away with it!

Christie

Christie

unread,
Mar 18, 2016, 8:51:32 PM3/18/16
to Ebean ORM
Both queries were using setDistinct(true).  When I remove that, the NPE from the first query doesn't happen and the IDs are set properly on the entities for the second query.  I changed both queries to start "find distinct foo" instead of "find foo" instead of using setDistinct(true).

Christie

Rob Bygrave

unread,
Mar 20, 2016, 4:54:00 PM3/20/16
to ebean@googlegroups
It would be good if you can create a test case for me to look at.

Maybe this was a change since 3.x but you should not be using setDistinct(true) on a query unless you do not want the @Id property included in the query.

Internally Ebean will set a SQL distinct when it needs to (it has always done that) when the sql rows will have duplicates. Again, you should NOT use setDistinct(true) unless you want to exclude the @Id property (fetch distinct customer name etc). From an ORM perspective this means that there is no Id so no persistence context or load context etc.

I'm not sure you are doing the right thing (or at least I think you very likely should not be using setDistinct(true) on your queries).  Have you checked the actual SQL?

If you create a test case and get it too me I'll have a look. I suspect you should just drop the distinct all together though.

Cheers, Rob.

Christie

unread,
Mar 28, 2016, 10:50:14 AM3/28/16
to Ebean ORM
You are right, I tested it and found I didn't need the distinct after all.  I don't remember why I originally used it.  Thanks!

Christie
Reply all
Reply to author
Forward
0 new messages