我試圖堅持使用JPA1與Hibernate實現兩個不同的實體。 該代碼,如下圖所示:非空屬性引用空值或瞬態值爲持久值
父實體類
@Entity
@Table(name = "parent")
public class Parent implements Serializable {
{...}
private Child child;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "child_id", nullable = "false")
public Child getChild() {
return child;
}
public void setChild(Child child) {
this.child = child;
}
兒童實體類
@Entity
@Table(name = "child")
public class Child implements Serializable {
private Integer id;
@Id
@Column(name = "child_id")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
測試用例
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:META-INF/application.xml")
@Transactional
public class ParentTest extends TestCase {
@PersistenceContext
private EntityManager entityManager;
@Test
public void testSave() {
Child child = new Child();
child.setId(1);
Parent parent = new Parent();
parent.setChild(child);
entityManager.persist(parent.getChild());
entityManager.persist(parent); // throws the exception
}
}
實體管理和交易應用。 xml
<tx:annotation-driven transaction-manager="transactionManager" />
<jee:jndi-lookup id="dataSource" jndi-name="java:/jdbc/myds" expected-type="javax.sql.DataSource" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="packagesToScan" value="com.mypackage" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter"›
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect>org.hibernate.dialect.Oracle10gDialect</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
當試圖插入父對象時,即使child在此操作之前被創建並持久化,hibernate也會拋出PropertyValueException異常,並指出child爲null或transient。奇怪的是,這隻在單元測試中失敗,而在真正的應用程序中,插入了一個預先插入的子項,這與預期一致。
PS: 我很清楚我可以映射孩子級聯堅持,但這不是這裏的主意。我只是想檢查這兩個工作是否獨立。
什麼類型是EntityManager?我找不到任何對insert()方法的引用。 – 2014-11-25 10:00:33
我認爲這可能與Junit方法中的事務處理有關。只有當孩子已經在數據庫中時(提交之後)才能插入父代。這將解釋爲什麼它在你的「真實」應用程序上工作而不是在這裏。你能分享你的application.xml文件嗎? – santedicola 2014-11-25 12:08:06
@PredragMaric我的不好。我正在使用堅持的方法。固定在帖子上。 – renke 2014-11-25 15:49:48