Próbuję zachować dwie różne jednostki przy użyciu JPA1, z implementacją Hibernate. kod na to, jak pokazano poniżej:Właściwość nie-pusta odwołuje się do wartości pustej lub przejściowej dla wartości trwałej
jednostka nadrzędna klasa
@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;
}
klasa jednostka Dziecko
@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;
}
}
przypadek testowy
@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
}
}
kierownik jednostki i transakcja na aplikacji. 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>
Podczas próby wstawienia obiektu nadrzędnego hibernacja powoduje wygenerowanie wyjątku PropertyValueException, informując, że dziecko ma wartość zerową lub jest tymczasowe, mimo że element potomny został utworzony i zachowywał się przed tą operacją. Dziwne jest to, że test kończy się niepowodzeniem, aw prawdziwej aplikacji z wcześniej wstawionym dzieckiem działa to zgodnie z oczekiwaniami.
PS: Jestem całkiem świadomy, że mogę mapować dziecko z kaskadą, ale nie jest to ideą tutaj. Chcę tylko sprawdzić, czy te dwie działają niezależnie.
Jakim typem jest 'EntityManager'? Nie mogę znaleźć żadnego odniesienia do metody "insert()". –
Myślę, że może to być związane z obsługą transakcji w metodzie Junit. Rodzic można wstawić tylko wtedy, gdy dziecko jest już w bazie danych (po zatwierdzeniu). To wyjaśniałoby, dlaczego nie działa tutaj na twojej "prawdziwej" aplikacji. Czy możesz udostępnić swój plik application.xml? – santedicola
@PredragMaric my bad. Używam metody persist. Naprawiono w poście. – renke