删除分离的对象时,Hibernate JPA没有异常

时间:2015-02-16 17:20:31

标签: java hibernate jpa

问题

我正在为JPA服务编写unittest,并期望在使用新创建的,因此分离的实体调用remove()时看到IllegalArgumentException(请参阅javadoc了解抛出的异常)。 我是否误解了分离实体的概念,或者这是Hibernate实现中的错误?

实施例

对于长长的例子感到抱歉,但我想要包含重现问题所需的一切。

TestEntity.java

@Entity
public class TestEntity {
    @Id
    @GeneratedValue
    private Long id;
    private String value;

    // Getter and setter omitted
}

TestEntityTest.java

public class TestEntityTest {
    @Test
    public void testDeletion() {
        final EntityManager entityManager = Persistence.createEntityManagerFactory("manager1").createEntityManager();

        final TestEntity entity = new TestEntity();

        // Not expected to be contained
        assertTrue(!entityManager.contains(entity));

        try {
            entityManager.getTransaction().begin();
            entityManager.remove(entity);
            entityManager.flush();
            entityManager.getTransaction().commit();
            fail("No exception thrown");
        }catch (IllegalArgumentException e) {
            // Expected when removing a detached entity
        }
    }
}

META-INF / persistence.xml中

<persistence 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"
             version="2.0">
    <persistence-unit name="manager1" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <class>org.hibernatetest.TestEntity</class>
        <properties>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
            <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver"/>
            <property name="javax.persistence.jdbc.user" value="sa"/>
            <property name="javax.persistence.jdbc.password" value=""/>
            <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:mem:unit-testing-jpa"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
            <property name="hibernate.max_fetch_depth" value="3"/>
        </properties>
    </persistence-unit>
</persistence>

的pom.xml

<project>
    <modelVersion>4.0.0</modelVersion>
    <name>persistence service</name>
    <groupId>jpa.example</groupId>
    <artifactId>persistence-service</artifactId>
    <version>1.0</version>

    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.3.8.Final</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.10</version>
        </dependency>
        <dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.19.0-GA</version>
        </dependency>

        <!-- TEST RESOURCES -->
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <version>2.3.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

    </dependencies>
</project>

1 个答案:

答案 0 :(得分:2)

您唯一的错误是全新的实体对象不是分离的,它是瞬态。有关详细信息,请查看this flow-chart lifecycle diagram

这里要说的是,对象可以有四个Hibernate生命周期阶段。

  • New / Transient对象在数据存储区中没有任何表示形式,并且与任何上下文无关。
  • 托管对象具有上下文并位于数据存储区中。
  • 分离的对象位于数据存储区中,但已从Hibernate上下文中删除
  • 删除的对象不再位于数据存储区中(或至少标记为要删除),但仍保持与上下文的连接。

按照javadoc的严格措辞,你的全新对象是一个实体而且它没有分离,因此代码中没有错误而没有抛出异常。