Duplicate entry exception

565 views
Skip to first unread message

Andrea Zilio

unread,
Jun 5, 2010, 1:02:46 PM6/5/10
to Ebean ORM
Hello, I just started using Ebean (I've used Hibernate in the past).

I'm having a Duplicate key error when saving an item, editing a
property and saving it again.

Here's the cutted-down code:

Person p = new Person();
p.setName("John");
p.setSurname("Do");
Ebean.save(p);
p.setSurname("DoE");
Ebean.save(p); // Here the
MySQLIntegrityConstraintViolationException("Duplicate entry '1' for
key 1") is raised

Here's the code of the Person POJO:

@Entity
public class Person {
@Id
private Integer id;
private String name;
private String surname;
// ... Classic setter and getters would follow ...
}

Note that adding a Timestamp Field and attaching the @Version
annotation to it solves the problem.... But why is this necessary?
I've not read anywhere that this is required. (Moreover @Version is
not mentioned in the user guide).

Thanks in advance

edge

unread,
Jun 5, 2010, 4:34:02 PM6/5/10
to Ebean ORM
You generally will use an @version property in any real world app.
However, I would have expected an update instead of an insert. This
may be a bug and I'll take a look at it.
Are you using enhancement?

Eddie

Andrea Zilio

unread,
Jun 5, 2010, 7:21:21 PM6/5/10
to Ebean ORM
Hmmmm... I don't understand...
What do you mean by "using enhancement"?

Andrea

Rob Bygrave

unread,
Jun 6, 2010, 10:27:22 PM6/6/10
to eb...@googlegroups.com
There are 2 ways of using Ebean:

1. Enhancement ... via javaagent, ant task, maven plugin, IDE (Eclipse or IDEA) plugin.

What this means is that the actual byte codes of the entity beans are modified.


2. Subclass generation / "Dynamic Proxies" ...

Ebean generates extra classes using its own class loader. Hibernate and OpenJPA also support this approach.


The best description of these 2 approaches (pro's, con's etc) is in the reference pdf guide. So have a look through that and fire back any questions after that.


Cheers, Rob.

Rob Bygrave

unread,
Jun 6, 2010, 10:30:24 PM6/6/10
to eb...@googlegroups.com
BTW: Without the @Version Ebean save() will check the Id value to determine insert or update so I'd be interested to see the code that you have used.

Ta, Rob.

Epper

unread,
Jun 7, 2010, 7:46:21 AM6/7/10
to eb...@googlegroups.com
Thank you very much for the explaination. I'll check and I'll let you know.
(In the mean time I'll post here the source code to reproduce the error)

Andrea Zilio

unread,
Jun 16, 2010, 6:13:40 AM6/16/10
to Ebean ORM
Here I am.

I've now understood the two different approaches and I can tell you
that using the Ebean Java Agent everything works fine, instead,
removing the VM arguments to load the java agent (which, if I've
correctly understood, makes eBean to use SubClass generation), the
exception is triggered on the second Ebean.save() call.

This time I've used H2 db engine and so the exception is a bit
different, but the problem should be exactly the same:
org.h2.jdbc.JdbcSQLException: Unique index or primary key violation:
"PRIMARY_KEY_F ON PUBLIC.CERTIFICATE(ID)"; SQL statement:
insert into certificate (id, name) values (?,?)

Here's my very simple code:
- Entity Class: http://pastebin.com/xLdWp8G7
- Simple test which raises the error: http://pastebin.com/w38LhFi6

Thanks!
Andrea

On Jun 7, 1:46 pm, Epper <m.ep...@gmail.com> wrote:
> Thank you very much for the explaination. I'll check and I'll let you know.
> (In the mean time I'll post here the source code to reproduce the error)
>
>
>
> On Mon, Jun 7, 2010 at 4:30 AM, Rob Bygrave <robin.bygr...@gmail.com> wrote:
> > BTW: Without the @Version Ebean save() will check the Id value to determine
> > insert or update so I'd be interested to see the code that you have used.
>
> > Ta, Rob.
>
> > On Mon, Jun 7, 2010 at 2:27 PM, Rob Bygrave <robin.bygr...@gmail.com>wrote:
>
> >> There are 2 ways of using Ebean:
>
> >> 1. Enhancement ... via javaagent, ant task, maven plugin, IDE (Eclipse or
> >> IDEA) plugin.
>
> >> What this means is that the actual byte codes of the entity beans are
> >> modified.
>
> >> 2. Subclass generation / "Dynamic Proxies" ...
>
> >> Ebean generates extra classes using its own class loader. Hibernate and
> >> OpenJPA also support this approach.
>
> >> The best description of these 2 approaches (pro's, con's etc) is in the
> >> reference pdf guide. So have a look through that and fire back any questions
> >> after that.
>
> >> Cheers, Rob.
>

Rob Bygrave

unread,
Jun 16, 2010, 7:26:13 AM6/16/10
to eb...@googlegroups.com
Can you add an @Version property?

This comes down to the issue of determining if a save() is an insert or an update for 'vanilla' beans (with enhanced beans the state is known - hence it works with the javaagent).

Ebean uses the value of @Version property to determine this and otherwise assumes an insert. In your example there is no @Version property so the second save() is also treated as an insert. The reason it did this was to support the case where you are copying data between DataSource's.

ENH 303 (in head) was just added and adds an explicit insert() method to EbeanServer which is probably a better more explicit approach for fetching beans from one DataSource to insert into another DataSource.

Coming back to @Version though... if at all possible you definately should have a @Version property so that you get more efficient update statements (more efficient where clauses in the update statements for optimistic concurrency checking). 

Andrea Zilio

unread,
Jun 16, 2010, 10:21:58 AM6/16/10
to Ebean ORM
OK, thanks for the explaination.

I'll just use the agent version ;)

Andrea

On Jun 16, 1:26 pm, Rob Bygrave <robin.bygr...@gmail.com> wrote:
> Can you add an @Version property?
>
> This comes down to the issue of determining if a save() is an insert or an
> update for 'vanilla' beans (with enhanced beans the state is known - hence
> it works with the javaagent).
>
> Ebean uses the value of @Version property to determine this and otherwise
> assumes an insert. In your example there is no @Version property so the
> second save() is also treated as an insert. The reason it did this was to
> support the case where you are copying data between DataSource's.
>
> ENH 303 (in head) was just added and adds an explicit insert() method to
> EbeanServer which is probably a better more explicit approach for fetching
> beans from one DataSource to insert into another DataSource.
>
> Coming back to @Version though... if at all possible you definately should
> have a @Version property so that you get more efficient update statements
> (more efficient where clauses in the update statements for optimistic
> concurrency checking).
>
Reply all
Reply to author
Forward
0 new messages