[ebean] @GeneratedValue inserted anyway when set

619 views
Skip to first unread message

Rien

unread,
May 12, 2010, 10:47:39 AM5/12/10
to Ebean ORM
Hi,

When we have something like this:

@Id
@GeneratedValue
@Column(name = "ID")
protected Integer identifier;

Sometimes we like to give the id field a value before we store it (so
we can identity the object). Ebean tries to store it and we get an sql
exception that we are not allowed to insert this field. I don't think
ebean should try to insert (or update) @GeneratedValue fields.

As a work around, this actually works for us:

@Id
@GeneratedValue
@Column(name = "ID", insertable=false, updatable=false)
protected Integer identifier;

Rien

Daryl Stultz

unread,
May 12, 2010, 11:28:16 AM5/12/10
to Ebean ORM

On May 12, 10:47 am, Rien <rnent...@gmail.com> wrote:
> Hi,
>
> Sometimes we like to give the id field a value before we store it (so
> we can identity the object).

Can you expand on that? Are you saying you might do this:

Entity a = new Entity();
a.setId(234);
...
Ebean.save(a);

Do you want/expect 234 to become the primary key of the record? Or is
234 just temporary as you might put "a" in a map or something before
saving it?

> Ebean tries to store it and we get an sql
> exception that we are not allowed to insert this field. I don't think
> ebean should try to insert (or update) @GeneratedValue fields.

I think I disagree. Working strictly with a database, no Ebean, no
Java, I would expect to be able to insert a record without specifying
an id and have one generated for me and also I could specify the id
explicitly in the insert statement. I do this from time to time (but
don't mix approaches on a single table). Perhaps your database doesn't
allow inserts on the PK column? If you aren't wanting 234 to become
the PK of the record, I think your work around is the right solution
rather than changing Ebean's handling.

Thanks for clarifying.

/Daryl

Rien

unread,
May 12, 2010, 11:46:50 AM5/12/10
to Ebean ORM
We indeed set the value to be able to identify it before it has been
stored in the database. We can of course set it to null before we save
it, but we are very lazy.

When a value is stated as a GeneratedValue I would expect Ebean not to
try to insert it even when it's set. But the work around works for us
to, so it's no skin of my back.

Rien

Daryl Stultz

unread,
May 12, 2010, 12:03:52 PM5/12/10
to Ebean ORM


On May 12, 11:46 am, Rien <rnent...@gmail.com> wrote:
> We indeed set the value to be able to identify it before it has been
> stored in the database.

Just out of curiosity, how can you tell when it's "new"?

> When a value is stated as a GeneratedValue I would expect Ebean not to
> try to insert it even when it's set.

If Ebean did not try to insert the PK value, I would think it should
also fail to save a new object instance if the ID is already set. I
believe JPA will fail, though I'm too lazy to verify it.

On the issue of identity (really aside from the PK insert issue) you
are setting the ID presumably because your hashcode/equals methods
refer to it. I'm only "reasonable" confident my implementations are
appropriate/complete. I'm not really sure what happens when I put a
new (null id) object in a map, for example. Would you mind sharing
your hashcode/equals implementation? I believe mine is fairly close to
the Ebean enhanced version:

PersistentEntity.java (superclass for all my entities):

@Override
public int hashCode() {
return getId() == null ? 0 : getId().hashCode();
}

@Override
public boolean equals(Object object) {
if (object == null) return false;
if (object == this) return true; // useful when both objects are new
and we are doing something like list.contains(entity)
if (object.getClass().equals(this.getClass())) { // must be same
subclass of PersistentEntity
Object id1 = ((PersistentEntity) object).getId();
Object id2 = getId();
if ((id1 == null) || (id2 == null)) return false;
else return id1.equals(id2);
} else {
return false;
}
}

Thanks.

/Daryl

Rob Bygrave

unread,
May 12, 2010, 6:23:00 PM5/12/10
to eb...@googlegroups.com
I'm not sure I fully understand this issue yet.

In my mind this depends on the Database and it's use of DB Identity or DB Sequences. I believe you are using intersystems cache and I don't know anything about that Database really (but I'm going to guess it has a Db Identity/Autoincrement approach).



> Ebean tries to store it and we get an sql exception that we are not allowed to insert this field.

Can you expand on this. Perhaps an example of the SQL.

In my mind I'm probably relating this to other DB's where you have DB Identity/Autoincrement ... and yet you can optionally specify the id as well.

I'm thinking that you want something along the lines... if an Id value is supplied generate a SQL insert that uses that value ... and if not then generate a SQL insert that will make use of the DB Identity/Autoincrement.

Is that what you mean or have I missed the point?


Cheers, Rob.

Rien

unread,
May 14, 2010, 3:54:27 AM5/14/10
to Ebean ORM
Apparently there are more way's to work with the GeneratedValue
annotation then that I was aware of. The concern is appreciated, but
it's actually a non issue for us.

The only reason we put something in the id before we store the object,
is to be able to select it from a list with an id value. We have a web
application and when the user selects the second row of the some newly
added objects in a list in the browser, we need to have a way to know
which one they selected. For this we set the id to some unique value,
then when we store it we want the database to set it (with whatever
unique value is next).

We only noticed that Ebean doesn't like this, so apparently in
hibernate this worked.

No idea how it actually 'should' work, we can work with how it works
right now.

So no problem as far as I am concerned,

Rien


On May 13, 12:23 am, Rob Bygrave <robin.bygr...@gmail.com> wrote:
> I'm not sure I fully understand this issue yet.
>
> In my mind this depends on the Database and it's use of DB Identity or DB
> Sequences. I believe you are using intersystems cache and I don't know
> anything about that Database really (but I'm going to guess it has a Db
> Identity/Autoincrement approach).
>
> > Ebean tries to store it and we get an sql exception that we are not
>
> allowed to insert this field.
>
> Can you expand on this. Perhaps an example of the SQL.
>
> In my mind I'm probably relating this to other DB's where you have DB
> Identity/Autoincrement ... and yet you can optionally specify the id as
> well.
>
> I'm thinking that you want something along the lines... if an Id value is
> supplied generate a SQL insert that uses that value ... and if not then
> generate a SQL insert that will make use of the DB Identity/Autoincrement.
>
> Is that what you mean or have I missed the point?
>
> Cheers, Rob.
>
Reply all
Reply to author
Forward
0 new messages