Please use the google group to ask questions - thanks.

by Rob 28 Feb 03:03
Released v2.4.0

We have just released v2.4.0 which includes:

11 enhancements
20 bug fixes

The main enhancements are:
- Transparent Encryption of properties
- 'Vanilla' mode
- Delete by id
- update() method (for stateless updates using entity beans)
- Offline DDL Generation
- EnumValue annotation

01 Mar 23:08
by Eabin

thanks rob!

just tried to upgrade from 1.1.0 to 2.4.0, but it seems there is an issue with @Transient maps:

java.lang.NullPointerException
at com.avaje.ebean.server.deploy.BeanMapHelp.(BeanMapHelp.java:46)
at com.avaje.ebean.server.deploy.BeanMapHelp.(BeanMapHelp.java:36)
at com.avaje.ebean.server.deploy.BeanCollectionHelpFactory.create(BeanCollectionHelpFactory.java:24)
at com.avaje.ebean.server.deploy.BeanPropertyAssocMany.initialise(BeanPropertyAssocMany.java:121)
at com.avaje.ebean.server.deploy.BeanDescriptor.initialiseOther(BeanDescriptor.java:613)
at com.avaje.ebean.server.deploy.BeanDescriptorManager.initialiseAll(BeanDescriptorManager.java:354)
at com.avaje.ebean.server.deploy.BeanDescriptorManager.deploy(BeanDescriptorManager.java:257)
at com.avaje.ebean.server.core.InternalConfiguration.(InternalConfiguration.java:135)
at com.avaje.ebean.server.core.DefaultServerFactory.createServer(DefaultServerFactory.java:189)
at com.avaje.ebean.server.core.DefaultServerFactory.createServer(DefaultServerFactory.java:121)
at com.avaje.ebean.server.core.DefaultServerFactory.createServer(DefaultServerFactory.java:67)
at com.avaje.ebean.EbeanServerFactory.create(EbeanServerFactory.java:63)
at com.avaje.ebean.Ebean$ServerManager.getWithCreate(Ebean.java:228)
at com.avaje.ebean.Ebean$ServerManager.(Ebean.java:184)
at com.avaje.ebean.Ebean$ServerManager.(Ebean.java:150)
at com.avaje.ebean.Ebean.(Ebean.java:144)
... 2 more

the map is declared as follows:
@Transient
private Map subscriptionMap;

and has a getter:
@Transient()
public Map getSubscriptionMap() {...}

kind regards,
-erwin

01 Mar 23:58
by Eabin

if i would have to guess (cannot compile head atm...so many dependencies) i would say this is the culprit:
BeanPropertyAssocMany.java:121:

public void initialise() {
super.initialise();

this.help = BeanCollectionHelpFactory.create(this);

if (!isTransient){

if (manyToMany){


////////////
i guess the creation of the this.help object should be moved inside the if-condition

02 Mar 00:27
by Rob

ok, thanks ... I'll take a look tonight.

02 Mar 07:03
by Rob

Logged as http://www.avaje.org/bugdetail-228.html

Fixed in HEAD.

If you can use the transient modifier (rather than @Transient) that is a workaround. Otherwise I can create a snapshot build.

Cheers, Rob.

02 Mar 10:07
by Eabin

thanks, you are as fast as ever!
i can use the modifier as a workaround, already tested it and it works.

02 Mar 11:46
by Eabin

got another one for you. this used to work fine in 1.1.0:

@OneToMany()
@OrderBy("creationDate")
@Where(clause="deleted=0")
private List comments;

now i get:
javax.persistence.PersistenceException: Query threw SQLException:Ambiguous column name DELETED; SQL statement:
select e.id c0
, ec.id c1, ec.cdate c2, ec.comment c3, ec.deleted c4, ec.user_id c5, ec.event_id c6
from event e
left outer join eventcomment ec on ec.event_id = e.id
where deleted=0 and e.id = ?
order by e.id , ec.cdate [90059-79] Query was:
select e.id c0
, ec.id c1, ec.cdate c2, ec.comment c3, ec.deleted c4, ec.user_id c5, ec.event_id c6
from event e
left outer join eventcomment ec on ec.event_id = e.id
where deleted=0 and e.id = ?
order by e.id , ec.cdate


com.avaje.ebean.server.query.CQueryEngine.findMany(CQueryEngine.java:202)
com.avaje.ebean.server.query.DefaultOrmQueryEngine.findMany(DefaultOrmQueryEngine.java:88)
com.avaje.ebean.server.core.OrmQueryRequest.findList(OrmQueryRequest.java:284)

02 Mar 12:31
by Rob

You need to add a "${ta}." prefix ... so it becomes:

@Where(clause="${ta}.deleted=0")


... where ta is short for Table Alias.

The issue with the sql is that without the table alias the 'deleted' column is ambiguous. I believe in 1.x the table alias' where worked out differently and automatically added.

Now we need to explicitly specify the "${ta}." part.

Cheers, Rob.

02 Mar 23:36
by Eabin

thanks, i'm slowly starting to see the bottom of this. but there is still one more. any idea where this might come from?

Caused by: java.lang.RuntimeException
at com.avaje.ebean.server.core.DefaultBeanLoader.loadMany(DefaultBeanLoader.java:152)
at com.avaje.ebean.server.core.DefaultServer.loadMany(DefaultServer.java:428)
at com.avaje.ebean.server.loadcontext.DLoadManyContext.loadMany(DLoadManyContext.java:143)
at com.avaje.ebean.common.AbstractBeanCollection.lazyLoadCollection(AbstractBeanCollection.java:142)
at com.avaje.ebean.common.BeanList.init(BeanList.java:107)
at com.avaje.ebean.common.BeanList.size(BeanList.java:393)
at tk.eabin.event.db.Event.hasNewComments(Event.java:524)
at tk.eabin.event.client.model.EventModel$EventExtractor.getNewComments(EventModel.java:32)
... 31 more

------------

in the source batch.size() = 1 and list.size() = 0, so you throw a runtimeexception. the resulting list should be empty too, so BeanList.size() should return 0.

02 Mar 23:39
by Eabin

thanks, i'm slowly starting to see the bottom of this. but there is still one more. any idea where this might come from?

Caused by: java.lang.RuntimeException
at com.avaje.ebean.server.core.DefaultBeanLoader.loadMany(DefaultBeanLoader.java:152)
at com.avaje.ebean.server.core.DefaultServer.loadMany(DefaultServer.java:428)
at com.avaje.ebean.server.loadcontext.DLoadManyContext.loadMany(DLoadManyContext.java:143)
at com.avaje.ebean.common.AbstractBeanCollection.lazyLoadCollection(AbstractBeanCollection.java:142)
at com.avaje.ebean.common.BeanList.init(BeanList.java:107)
at com.avaje.ebean.common.BeanList.size(BeanList.java:393)
at tk.eabin.event.db.Event.hasNewComments(Event.java:524)
at tk.eabin.event.client.model.EventModel$EventExtractor.getNewComments(EventModel.java:32)
... 31 more

------------

in the source batch.size() = 1 and list.size() = 0, so you throw a runtimeexception. the resulting list should be empty too, so BeanList.size() should return 0.

02 Mar 23:42
by Eabin

btw: this happens when querying the size of the list with the @Where(clause="${ta}.deleted=0").
when i remove the clause, everything is fine and dandy. although the condition would have no effect, since the list should be empty in both cases.

02 Mar 23:50
by Eabin

and one more note: this seems to happen only if the result list is empty.

03 Mar 00:15
by Eabin

i have a run tonight:
is there any way to use IDENTITY instead of SEQUENCE for h2 database? my db uses auto-generated ids everywhere, so all inserts fail miserably.

03 Mar 09:59
by Rob

DefaultBeanLoader.loadMany(DefaultBeanLoader.java:152)

... hmmm, looking at this now.

03 Mar 10:03
by Rob

>> use IDENTITY instead of SEQUENCE for h2 database?

In H2Platform ...
this.dbIdentity.setIdType(IdType.SEQUENCE);

... would need to change to:

ntity.setIdType(IdType.IDENTITY);

Hmmm.

03 Mar 10:09
by Rob

>> note: this seems to happen only if the result list is empty.

Can you show me the actual sql query prior to the exception. It should be a lazy loading query. In theory it should actually return 1 row (and not 0) ... as that is number of top level objects.

03 Mar 10:14
by Rob

If you can change the code ...

if (list.size() != batch.size()) {
        String msg = "Batch lazy loading on Many "+many.getFullBeanName();
        msg += " returned incorrect row count? "+list.size() +" <> "+batch.size();
        msg += ". idList["+idList+"] sql:"+query.getGeneratedSql();
        throw new RuntimeException(msg);
}
03 Mar 10:20
by Rob

The idList will just have 1 value ... and we should be able to check that against the sql to see what is returned.

03 Mar 12:03
by Eabin

the only two sql statements that are executed in my test-case:
[code]

select e.id c0, e.startdate c1, e.enddate c2, e.cdate c3, e.minpeople c4, e.maxpeople c5, e.comment c6, e.canceled c7, e.reason c8, e.deleted c9, e.archived c10, e.creator_id c11, e.category_id c12, e.location_id c13
from event e
where e.id = ?


select e.id c0
, ec.id c1, ec.cdate c2, ec.comment c3, ec.deleted c4, ec.user_id c5, ec.event_id c6
from event e
left outer join eventcomment ec on ec.event_id = e.id
where ec.deleted=0 and e.id = ?
order by e.id , ec.cdate

[/code]

03 Mar 12:04
by Eabin

btw: how do i post code so that < and > are not eaten?

03 Mar 12:06
by Rob

<pre class="java" >
...
put java code in here...
...
</pre>

03 Mar 12:07
by Eabin

getFullBeanName() = tk.eabin.event.db.Event.comments
list.size = 0
batch.size = 1
idList = [1290]
generatedSql = select e.id c0
, ec.id c1, ec.cdate c2, ec.comment c3, ec.deleted c4, ec.user_id c5, ec.event_id c6
from event e
left outer join eventcomment ec on ec.event_id = e.id
where ec.deleted=0 and e.id = ?
order by e.id , ec.cdate

03 Mar 12:10
by Rob

Ok, I think I see the problem:

select e.id c0
, ec.id c1, ec.cdate c2, ec.comment c3, ec.deleted c4, ec.user_id c5, ec.event_id c6
from event e
left outer join eventcomment ec on ec.event_id = e.id
where ec.deleted=0 and e.id = ?
order by e.id , ec.cdate

I think we need a nvl type function around the "ec.deleted=0" ...

Aka ... this has the effect of making the left outer join ... just a join and hence will return no rows.

Hmmm. Maybe that is actually ok in the lazy loading case... and in fact the code that checks 1 <> 0 ... should just not be there.

03 Mar 12:13
by Rob

where ec.deleted=0 and e.id = ?

->

where (ec.deleted is null OR ec.deleted=0) and e.id = ?

So you could try ...

@Where(${ta}.deleted is null OR ${ta}.deleted=0})

03 Mar 12:18
by Rob

@Where(nvl(${ta}.deleted,0) = 0}) ... or isnull() - depends on the DB

03 Mar 12:33
by Eabin

adding the null check works, but it seems kind of counter-intuitive to me.

03 Mar 12:35
by Eabin

put removing the check in DefaultBeanLoader leads to another exception:

Exception in thread "main" java.lang.NullPointerException
at com.avaje.ebean.common.BeanList.size(BeanList.java:394)
at tk.eabin.event.db.Event.hasNewComments(Event.java:524)
at tk.eabin.event.server.ServerRunner.run(ServerRunner.java:47)
at tk.eabin.event.server.ServerRunner.main(ServerRunner.java:42)
at test.DebugServer.main(DebugServer.java:23)

03 Mar 12:39
by Rob

In this case we are lazy loading the many... so you are correct, in this case it really doesn't make a real difference.

That is, it is really a bug with the check:

if (list.size() != batch.size()) {

}

It is actually incorrect in this case. It assumed the join would always be effectively an outer join... and there would always be the same number of top level beans fetched as id's - in this case 1.

However, that is a bad assumption.

I'll log this as a bug - and remove that checking code.

03 Mar 12:47
by Rob

Exception in thread "main" java.lang.NullPointerException
at com.avaje.ebean.common.BeanList.size(BeanList.java:394)
at tk.eabin.event.db.Event.hasNewComments(Event.java:524)

Yup. I think that the query returns 0 rows... so it is not setting an empty list (it is still null) ... and that means the underlying list in BeanList is still null.

I think that is the bug there - I'll see if I can reproduce.

03 Mar 12:55
by Rob

Yup - reproduced.

java.lang.NullPointerException
at com.avaje.ebean.common.BeanList.size(BeanList.java:394)
at com.avaje.tests.batchload.TestEmptyManyLazyLoad.test(TestEmptyManyLazyLoad.java:28)

03 Mar 13:07
by Rob
03 Mar 13:12
by Rob

Fixed in HEAD now.

03 Mar 13:16
by Eabin

thanks, my application now runs without exceptions on a brief test.
but i need IDENTITY instead of SEQUENCE, could you make that into a configurable option via ebean.properties?

03 Mar 13:28
by Rob

Yup - already done so - http://www.avaje.org/bugdetail-230.html

03 Mar 13:37
by Eabin

many thanks for being such a responsive developer. you most definitely need a donate button - i feel the urge of buying you a beer or two.

03 Mar 20:50
by Rob

Ha ha ... funny as I put a Donate button on the download page last night :)

Ebean got it's first donation last week :)

Cheers, Rob.

Create a New Topic

Title:
Body:
 
Introduction User Guide (pdf) Install/Configure Public JavaDoc Whitepapers
General Database Specific Byte Code Deployment Annotations Features
Top Bugs Top Enhancements
woResponse