Hi,
a simple code causing the EntityExistsException: Attempt to persist
detached object exception, which, in my opinion, should not be the
case. It happens only when the @Id field is of Long type (NOT the
primitive type) and works when the @Id field is long (the primitive
long).
I'll start with the code causing trouble (btw/ Hibernate or Toplink as
a PU works without trouble!!):
#v+
public static void insertUsingMerge()
{
User u = new User();
u.setName("s");
em.getTransaction().begin();
em.merge(u);
em.getTransaction().commit();
}
#v-
where:
#v+
private static EntityManagerFactory emf =
Persistence.createEntityManagerFactory("OpenjJPA_PU");
private static EntityManager em = emf.createEntityManager();
#v-
The most important part, the User entity (an excerpt)
#v+
@Entity
@Table(name = "users")
public class User
{
private Long id;
public User()
{
}
@Id
@GeneratedValue(generator="o", strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name="o",sequenceName="hib_seq",allocationSize=1)
public Long getId()
{
return id;
}
...
#v-
The persistence unit configuration (nothing interesting here):
#v+
<persistence-unit name="OpenjJPA_PU" transaction-type="RESOURCE_LOCAL">
<provider>
org.apache.openjpa.persistence.PersistenceProviderImpl
</provider>
<class>kk.orm.User</class>
<properties>
<property name="openjpa.ConnectionURL" ... (standard
postgresql stuff)
<property name="openjpa.ConnectionDriverName" ...
<property name="openjpa.ConnectionUserName" ...
<property name="openjpa.ConnectionPassword" ...
<property name="openjpa.Log" value="DefaultLevel=WARN,
Tool=INFO" />
</properties>
</persistence-unit>
#v-
The first thing that came to my mind was to analyse the spec. u is a
new object, hence (quoting ejb 3 persistence specification):
The semantics of the merge operation applied to an entity X are as follows:
• If X is a new entity instance, a new managed entity instance X' is
created and the state of X is
copied into the new managed entity instance X'.
So it should work. Of course I agree with the Exception, that
persisting a detached objects is invalid, as far as the specification
is concerned, but I don't see *where* I'm doing this. All I do is a
simple merge on a *new* object.
On the other hand, quoting the spec: "The merge operation allows for
the propagation of state from detached entities onto persistent
entities managed by the EntityManager.". This is a bit confusing.
Why does OpenJPA try to "persist a detached object" when I call merge
on an new object whose @Id is of type Long? And btw, Hibernate and
Toplink allow me such an operation, who's right?
First I thought, that only primitive types are allowed, but then I saw
an example in the spec (e.g. section 9.1.8 Id Annotation)
@Id
@GeneratedValue(strategy=TABLE, generator="CUST_GEN")
@Column(name="CUST_ID")
Long id;
and I've stopped searching if it's the case :)
Is it a bug or do I confuse something? I'm quite new to OpenJPA, I've
been using only Hibernate before and might misunderstand something.
Thanks for any help,
--
Regards, and thanks for any hints,
Kornel