Hibernate不会将相关实体存储在SQL Server数据库中

时间:2013-11-17 15:58:11

标签: sql-server hibernate hibernate-annotations

我正在努力解决一个问题。 我有当前的设置: -Spring版本:3.2.0.RELEASE -Hibernate版本:3.5.0-Final -Tomcat webserver

我正在构建一个应用程序,用于存储和提取单个对象到SQL Server DB中。 我想在Hibernate中使用注释。 我可以像我想要的那样构建我的对象,但是当我存储它时,只存储根对象,而不是它的相关对象。

使问题更简单一些。我有一个个人对象,每个人都可以获得0或更多的文凭:

@XmlRootElement
@Entity
@Table(name="INDIVIDUALS")
public class Individual {

@Id
@Column(name="SSIN", nullable=false)
private String ssin;

@XmlElementWrapper(name = "healthCareProfessionals")
@XmlElement(name = "healthCareProfessional")
@OneToMany(mappedBy="individual", fetch=FetchType.EAGER)
private Set<HealthCareProfessional> healthCareProfessionals = new HashSet<>();

@XmlElementWrapper(name = "diplomas")
@XmlElement(name = "diploma")
@OneToMany(mappedBy="individual", fetch=FetchType.EAGER)
private Set<Diploma> diplomas = new HashSet<>();

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

@Column(name="FIRST_NAME")
private String firstName;

@Column(name="MIDDLE_NAME")
private String middleName;

@Column(name="SEX")
private Sex sex;

@Column(name="BIRTH_DATE")
@XmlJavaTypeAdapter(DateAdapter.class)
private Date birthDate;

@Column(name="DEATH_DATE")
@XmlJavaTypeAdapter(DateAdapter.class)
private Date deathDate;

public Individual() {}

public Individual (String ssin, Set<Diploma> diplomas, String firstName, String lastName, String middleName, Sex sex, Date birthDate, Date deathDate) {
    this.ssin = ssin;
    this.healthCareProfessionals = healthCareProfessionals;
    this.diplomas = diplomas;
    this.firstName = firstName;
    this.lastName = lastName;
    this.middleName = middleName;
    this.sex = sex;
    this.birthDate = birthDate;
    this.deathDate = deathDate;
}

public String getSsin() {
    return ssin;
}

public void setSsin(String ssin) {
    this.ssin = ssin;
}

public String getLastName() {
    return lastName;
}

public void setLastName(String lastName) {
    this.lastName = lastName;
}

public String getFirstName() {
    return firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

public String getMiddleName() {
    return middleName;
}

public void setMiddleName(String middleName) {
    this.middleName = middleName;
}

public Sex getSex() {
    return sex;
}

public void setSex(Sex sex) {
    this.sex = sex;
}

public Set<Diploma> getDiplomas() {
    return diplomas;
}

public void addDiploma(Diploma diploma) {
    this.diplomas.add(diploma);
}

public void addDiplomas(Collection<Diploma> diplomas) {
    if (this.diplomas == null){
        this.diplomas = new HashSet<>() ;
    }
    this.diplomas.addAll(diplomas);

}

public Set<HealthCareProfessional> getHealthCareProfessionals() {
    return healthCareProfessionals;
}

public void addHealthCareProfessional(HealthCareProfessional healthCareProfessional) {
    this.healthCareProfessionals.add(healthCareProfessional);
}

文凭实体的定义如下:

@Entity
@Table(name="DIPLOMAS", uniqueConstraints = {
    @UniqueConstraint(columnNames = "DIPLOMA_ID"),
    @UniqueConstraint(columnNames = "CODE")})
public class Diploma {

@Id
@GeneratedValue(strategy= GenerationType.TABLE)
@Column(name="DIPLOMA_ID", unique=true, nullable=false)
private int id;

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

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

@Column(name="OBTAINING_DATE", nullable=false)
@XmlJavaTypeAdapter(DateAdapter.class)
private Date obtainingDate;

@ManyToOne
@JoinColumn(name="SSIN")
private Individual individual;

public Diploma() {}

public Diploma (String code, String name, Date obtainingDate, Individual individual) {
    this.code = code;
    this.name = name;
    this.obtainingDate = obtainingDate;
    this.individual = individual;
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getCode() {
    return code;
}

public void setCode(String code) {
    this.code = code;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@XmlTransient
public Individual getIndividual() {
    return individual;
}

public void setIndividual(Individual individual) {
    this.individual = individual;
}

使用正确的外键创建表:

CREATE TABLE INDIVIDUALS (
SSIN VARCHAR(11) NOT NULL PRIMARY KEY,
LAST_NAME VARCHAR(255),
FIRST_NAME VARCHAR(255),
MIDDLE_NAME VARCHAR(255),
SEX VARCHAR(10),
BIRTH_DATE DATETIME,
DEATH_DATE DATETIME);

CREATE TABLE DIPLOMAS (
DIPLOMA_ID BIGINT IDENTITY(1,1) PRIMARY KEY,
CODE VARCHAR(255) NOT NULL,
INDIVIDUAL_ID VARCHAR(11) NOT NULL,
NAME VARCHAR(255) NOT NULL,
OBTAINING_DATE DATETIME NOT NULL,
CONSTRAINT INDIVIDUAL_FK FOREIGN KEY(INDIVIDUAL_ID) REFERENCES INDIVIDUALS(SSIN));

我可以在我的应用程序中构建Object对象:

<individual>
    <healthCareProfessionals>
        <healthCareProfessional>
            <specialityApprovals/>
            <id>0</id>
            <NIHII_number>32030586</NIHII_number>
            <NIHII_qualificationCode>10,001</NIHII_qualificationCode>
            <profession>
                <authenticSource>EHP</authenticSource>
                <code>DENTIST</code>
                <name>Tandarts</name>
                <type>profession type</type>
            </profession>
        </healthCareProfessional>
        <healthCareProfessional>
            <specialityApprovals>
                <specialityApproval>
                    <authenticSource>FPS_PH</authenticSource>
                    <code>MPC3</code>
                    <description>GERIATRIE</description>
                    <type>specialty type</type>
                </specialityApproval>
            </specialityApprovals>
            <id>0</id>
            <NIHII_number>10013368</NIHII_number>
            <NIHII_qualificationCode>10,123</NIHII_qualificationCode>
            <profession>
                <authenticSource>EHP</authenticSource>
                <code>PHYSICIAN</code>
                <name>Geneesheer</name>
                <type>profession type</type>
            </profession>
        </healthCareProfessional>
        <healthCareProfessional>
            <specialityApprovals/>
            <id>0</id>
            <NIHII_number>54049388</NIHII_number>
            <NIHII_qualificationCode>10,001</NIHII_qualificationCode>
            <profession>
                <authenticSource>EHP</authenticSource>
                <code>PHYSIOTHERAPIST</code>
                <name>Fysiotherapeut</name>
                <type>profession type</type>
            </profession>
        </healthCareProfessional>
        <healthCareProfessional>
            <specialityApprovals/>
            <id>0</id>
            <NIHII_number>40003887</NIHII_number>
            <NIHII_qualificationCode>10,123</NIHII_qualificationCode>
            <profession>
                <authenticSource>EHP</authenticSource>
                <code>NURSE</code>
                <name>Verpleegkundige</name>
                <type>profession type</type>
            </profession>
        </healthCareProfessional>
        <healthCareProfessional>
            <specialityApprovals/>
            <id>0</id>
            <NIHII_number>29001416</NIHII_number>
            <NIHII_qualificationCode>10,001</NIHII_qualificationCode>
            <profession>
                <authenticSource>EHP</authenticSource>
                <code>PHARMACIST</code>
                <name>Apotheker</name>
                <type>profession type</type>
            </profession>
        </healthCareProfessional>
    </healthCareProfessionals>
    <diplomas>
        <diploma>
            <code>010EEE</code>
            <id>0</id>
            <name>Diploma arts verkregen in EEE </name>
        </diploma>
        <diploma>
            <code>010EEE</code>
            <id>0</id>
            <name>Diploma arts verkregen in EEE </name>
        </diploma>
        <diploma>
            <code>010EEE</code>
            <id>0</id>
            <name>Diploma arts verkregen in EEE </name>
        </diploma>
        <diploma>
            <code>010EEE</code>
            <id>0</id>
            <name>Diploma arts verkregen in EEE </name>
        </diploma>
        <diploma>
            <code>010EEE</code>
            <id>0</id>
            <name>Diploma arts verkregen in EEE </name>
        </diploma>
        <diploma>
            <code>010EEE</code>
            <id>0</id>
            <name>Diploma arts verkregen in EEE </name>
        </diploma>
        <diploma>
            <code>010EEE</code>
            <id>0</id>
            <name>Diploma arts verkregen in EEE </name>
        </diploma>
        <diploma>
            <code>010EEE</code>
            <id>0</id>
            <name>Diploma arts verkregen in EEE </name>
        </diploma>
    </diplomas>
    <birthDate>1982-05-12</birthDate>
    <firstName>HANNES HANS</firstName>
    <lastName>DE CLERCQ</lastName>
    <sex>male</sex>
    <ssin>67111433946</ssin>
</individual>

当我想存储对象时,只存储INDIVIDUALS表中的值,但不存储在DIPLOMAS表中...

我真的不知道我做错了什么

这是我的applicationContext:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xsi:schemaLocation="       http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context.xsd
   http://www.springframework.org/schema/tx
   http://www.springframework.org/schema/tx/spring-tx.xsd">

<context:component-scan base-package="be.healthconnect.pwg" />
<tx:annotation-driven />

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
      destroy-method="close">
    <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
    <property name="url" value="jdbc:sqlserver://localhost\SQLEXPRESS;databaseName=PWG" />
    <property name="username" value="root" />
    <property name="password" value="root" />
</bean>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="MyApplicationPersistanceUnitName"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="databasePlatform" value="org.hibernate.dialect.SQLServerDialect"/>
            <property name="generateDdl" value="false"/>
            <property name="showSql" value="false"/>
        </bean>
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
        </props>
    </property>
    <property name="dataSource" ref="dataSource"/>
</bean>

<bean id="jpaVendorAdaptor"
      class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="emf" />
</bean>

这是我的persistance.xml,它位于META-INF文件夹中:

<?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="individual" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>be.healthconnect.pwg.domain.Individual</class>
</persistence-unit>

我使用EntityManagerFactory的persist方法存储我构造的对象:

@Transactional(propagation = Propagation.REQUIRED)
public void addIndividual(Individual individual) {
   em.persist(individual);
}

我希望填写INDIVIDUALS和DIPLOMAS表,但不幸的是只填写了INDIVIDUALS表:

Individuals table filled up

Diplomas table not filled in

帮助将受到高度赞赏!

1 个答案:

答案 0 :(得分:1)

更改如下。个人处于关系的非拥有(反向)方面,因此您需要设置双方以便级联工作。

public void addDiploma(Diploma diploma) {
    this.diplomas.add(diploma);
    diploma.setIndividual(this);
}

再次查看,您实际上似乎没有为此关系添加任何级联选项,因此您还需要将cascade = XYZ添加到@OneToMany映射。