【发布时间】:2015-01-22 15:13:26
【问题描述】:
我正在尝试使用 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
}
}
application.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>
当试图插入父对象时,hibernate 会抛出一个 PropertyValueException,说 child 是 null 或暂时的,即使 child 是在此操作之前创建并持久化的。奇怪的是,这仅在单元测试中失败,而在实际应用程序中,使用预先插入的孩子,这可以按预期工作。
PS: 我很清楚我可以用级联持续映射孩子,但这不是这里的想法。我只是想检查这两个是否独立工作。
【问题讨论】:
-
EntityManager是什么类型?我找不到任何对insert()方法的引用。 -
我认为可能与Junit方法中的事务处理有关。只有当孩子已经在数据库中(提交后)时,才能插入父母。这可以解释为什么它适用于您的“真实”应用程序而不是在这里。你能分享你的 application.xml 文件吗?
-
@PredragMaric 我的错。我正在使用持久化方法。固定在帖子上。
-
@santedicola 从 application.xml 添加了事务和实体管理器配置
-
你能告诉我们堆栈跟踪吗?
标签: java hibernate jpa orm hibernate-mapping