Search code examples
javaspringjpaeclipselinkquerydsl

Persist always generates an insert query


Fist of all, I'm using EclipseLink 2.5.2, ojdbc6, spring-orm 4.1.1 and QueryDSL 3.7.1.

I don't understand why my objects are not in my persistence context (or is this how it should be?). I'm using QueryDSL to query my objects, however when I try to persist such an object using entitymanager.persist() it always creates an insert statement resulting in in a duplicated primarykey exception. Calling refresh() on the object crashes with java.lang.IllegalArgumentException: Can not refresh not managed object. Using merge() works fine however that's not what I want. I need to keep my original reference to the saved object.

persistence.xml

<persistence version="2.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

    <persistence-unit name="XXXXXX"
        transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>jdbc/XXXXX</jta-data-source>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <property name="eclipselink.weaving" value="static" />
            <property name="eclipselink.target-database" value="Oracle11" />
        </properties>
    </persistence-unit>
</persistence>

The entitymanager used to create the JPAQuery and to refresh/merge/persist are the same.

If you need more information/configurations/etc. please leave a comment. I'm really stuck and can't wrap my head around what the reason could be and what other information could be useful to you guys.


Solution

  • EntityManager.persist() is used to make a transient instance persistent. In this case transient (a term used by Hibernate, but valid for other persistence providers as well) means an entity which doesn't have a representation in the persistence context or the underlying datastore. It's not meant to be used on entities already present in the database. Use merge() to update persistent entities.

    There is an article about the subject with a nice state diagram representing the states an entity can be in and the transitions between those states: Entity states