Java – non null attributes refer to null or instantaneous values of persistent values
I try to use JPA 1 to persist two different entities and use hibernate to implement it
Parent entity class
@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; }
Sub entity class
@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; } }
test case
@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 } }
Entity manager and application Transactions on 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>
When attempting to insert the parent object, hibernate will throw a propertyvalueexception, that is, the child will create and persist it before this operation, that is, null or transient Strangely, this only fails in unit tests. In practical applications, using pre inserted children works as expected
PS: I know very well that I can map children with cascade persistence, but this is not the idea here I just want to check whether these two work independently
Solution
The problem here is that you are using the set value to maintain the parent table
@Test public void testSave() { Child child = new Child(); child.setId(1); entityManager.persist(child); Parent parent = new Parent(); parent.setChild(child); entityManager.persist(parent); }
Try this to save the child, and then save the parent process