Laures
Laures

Reputation: 5489

No Persistence Exception when persist() is called with an entity that violates a unique constraint

I have a unique constraint on one property of my entity:

Table(uniqueConstraints = @UniqueConstraint(name = "UniqueByEmail", columnNames = "email"))
public class Player implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column(name = "email")
    private String email;
    ...
}

In my DAO i want to throw an appropriate exception when something tries to create a new player that would violate this constraint:

public Player create(String email, String password) {
    Player player = new Player(email, password);
    try {
        em.persist(player);
    } catch (Exception e) {
        System.err.println("I GOT AN EXCEPTION : " + e.getClass());
    }
    return player;
}

Unfortunately nothing happens. when i call flush() on the entity manager i get the persistence exception as a result of this call, but not when i call persist().

This behaviour differs from the behaviour of hibernate, so i think i misconfigured something.

Any help is greatly appreciated.

Persistence.xml: org.eclipse.persistence.jpa.PersistenceProvider model.GameInstanceAccount Player

spring applicationContext.xml:

<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="persistence-unit" />
    <property name="jpaDialect" ref="jpaDialect" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter" />
    </property>
</bean>

<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" />

<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
    <property name="generateDdl" value="true" />
    <property name="databasePlatform" value="org.eclipse.persistence.platform.database.HSQLPlatform" />
</bean>

Upvotes: 0

Views: 510

Answers (1)

Alex Barnes
Alex Barnes

Reputation: 7218

when i call flush() on the entity manager i get the persistence exception as a result of this call, but not when i call persist()

This is expected behaviour. The persist call only attaches the transient entity to the current persistence session making it managed. The constraint applies in the database and so will only be applied when the persistence session is flushed and new entities are inserted to the database.

This is summed up in this blog as follows:

A newly created instance of the entity class is passed to the persist method. After this method returns, the entity is managed and planned for insertion into the database. It may happen at or before the transaction commits or when the flush method is called.

Upvotes: 1

Related Questions