2012-08-27 1 views
0

Mon test échoue lors de l'utilisation de relations @OneToMany ou @ManyToOne.Hibernate, Spring Données: @OneToMany relation et vice versa ne fonctionne pas

Entités:

@Entity 
@Table(name = "CONTACTS") 
public class Contact implements Serializable { 

    private static final long serialVersionUID = 8841543709585000683L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "CONTACT_ID") 
    private Long contactId; 

    @Column(name = "CONT_NAME", nullable = false) 
    private String name; 

    @Column(name = "LAST_NAME") 
    private String lastName; 

    @Column(name = "NICK_NAME") 
    private String nickName; 

    @OneToMany(targetEntity = TelephoneNumber.class, fetch = FetchType.EAGER, mappedBy = TelephoneNumber.CONTACT_FIELD_NAME, cascade = CascadeType.ALL) 
    private Set<TelephoneNumber> telephoneNumbers = new HashSet<TelephoneNumber>(0); 

    getters(); 
    setters() 
} 

@Entity 
@Table(name = "TELEPHONE_NUMBERS") 
public class TelephoneNumber implements Serializable { 

    private static final long serialVersionUID = 4459049334214768290L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "NUMBER_ID") 
    private Long telephoneNumberId; 

    @Enumerated(EnumType.ORDINAL) 
    @Column(name = "TELEPHONE_TYPE", nullable = false) 
    private TelephoneType telephoneType; 

    @Column(name = "TELEPHONE_NUMBER") 
    private String telephoneNumber; 

    @JoinColumn(name = "CONTACT_ID", nullable = false) 
    @ManyToOne(targetEntity = Contact.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    private Contact contact; 
    public final static String CONTACT_FIELD_NAME = "contact"; 

    getters(); 
    setters(); 
} 

contexte de printemps:

<import resource="classpath*:spring/dbs-repository-context.xml" /> 

<!-- Activates JPA's @PersistenceContext and @PersistenceUnit (if available) 
    annotations to be detected in bean classes. --> 
<context:annotation-config /> 

<!-- Enable Transaction using @Transactional annotation --> 
<tx:annotation-driven /> 

<bean id="daTM" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager" 
    p:dataSource-ref="dataSource" /> 

<!-- Create local transaction manager --> 
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" 
    p:entityManagerFactory-ref="entityManagerFactory" lazy-init="true" 
    p:dataSource-ref="dataSource" /> 

<!-- Create EntityManagerFactory for injection into services. --> 
<bean id="entityManagerFactory" 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
    p:dataSource-ref="dataSource" p:persistenceXmlLocation-ref="persistenceXmlLocation"> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
      <property name="showSql" value="true" /> 
     </bean> 
    </property> 
</bean> 

<!-- Database access configuration --> 
<bean id="persistenceXmlLocation" class="java.lang.String"> 
    <constructor-arg value="classpath*:META-INF/persistence.xml"></constructor-arg> 
</bean> 

<context:property-placeholder 
    location="classpath:spring/jdbc.properties" /> 

<!-- Dev's env DataSource --> 
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 
    destroy-method="close"> 
    <property name="driverClassName" value="${jdbc.driver}" /> 
    <property name="url" value="${jdbc.url}" /> 
    <property name="username" value="${jdbc.username}" /> 
    <property name="password" value="${jdbc.password}" /> 
</bean> 

persistence.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<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" xmlns="http://java.sun.com/xml/ns/persistence"> 
    <persistence-unit name="contactManagerPU"> 
     <provider>org.hibernate.ejb.HibernatePersistence</provider> 

     <class>com.snp.cm.persistency.contact.Contact</class> 
     <class>com.snp.cm.persistency.contact.TelephoneNumber</class> 

     <exclude-unlisted-classes>false</exclude-unlisted-classes> 

     <properties> 
      <property name="hibernate.max_fetch_depth" value="3" /> 
     </properties> 
    </persistence-unit> 
</persistence> 

Et échoué au test (failes sur la dernière cause de 0 téléphones assert mais d'autres champs existent) :

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath*:spring/dbs-application-context.xml" }) 
@Transactional 
public class ContactRepositoryTest { 

    @Autowired 
    private ContactRepository contactRepository; 
    @Autowired 
    private TelephoneNumberRepository telephoneNumberRepository; 

    @Test 
    public void testRepositorySaveMethod() { 
     Contact contact = new Contact(); 
     contact.setLastName("Carter"); 
     contact.setName("John"); 
     contact.setNickName(null); 
     contact = this.contactRepository.save(contact); 
     Assert.assertNotNull(contact.getContactId()); 

     TelephoneNumber telephoneNumber1 = new TelephoneNumber(); 
     telephoneNumber1.setTelephoneNumber("093 7674441"); 
     telephoneNumber1.setContact(contact); 
     telephoneNumber1.setTelephoneType(TelephoneType.HOME); 
     this.telephoneNumberRepository.save(telephoneNumber1); 

     TelephoneNumber telephoneNumber2 = new TelephoneNumber(); 
     telephoneNumber2.setTelephoneNumber("093 7674441"); 
     telephoneNumber2.setContact(contact); 
     telephoneNumber2.setTelephoneType(TelephoneType.MOBILE); 
     this.telephoneNumberRepository.save(telephoneNumber2); 

     contact = this.contactRepository.findOne(contact.getContactId()); 

     Assert.assertEquals(2, contact.getTelephoneNumbers().size()); 
    } 
} 

Quelle peut être la raison? J'ai essayé de changer FetchType mais cela n'a pas fonctionné pour moi.

Répondre

0

vous avez deux options dans le test:

  • Faire un flush de mettre à jour l'entité mère (avant "Assert.assertEquals (.." ajouter "session.flush()")
  • Ajouter la les enfants directement par l'entité mère (contact.getTelephoneNumbers(). Ajouter (entité)), avec cascade, se rapportent automatiquement.

Cordialement,

Questions connexes