【问题标题】:How to map java.util.Map with associations in hibernate xml?如何映射 java.util.Map 与休眠 xml 中的关联?
【发布时间】:2014-08-04 17:26:34
【问题描述】:

我的实体Person如下:

@Entity
@Table(name = "Person")
@Inheritance(strategy = InheritanceType.JOINED)
public class Person implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "personName", length = 16, nullable = false)
    private String name;
.....................
}

我的实体Teacher如下:

@Entity
@Table(name = "teacher")
@PrimaryKeyJoinColumn(name = "PersonId")
public class Teacher extends Person implements Serializable {

    private Map<String, Child> childByName = new HashMap<>();
        ......................................
}

我有实体Child如下:

@Entity
@Table(name = "CHILD")
@PrimaryKeyJoinColumn(name = "PersonId")
public class Child extends Person implements Serializable {
        ..............................
}

映射Teacher.childByName 应将Child 实体的name 属性映射为键,将Child 实体映射为值。 TeacherChild 之间的关系是一对多的。

我需要此映射为 xml 格式。 现在我在 Person.hbm.xml 中做了这个:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.masterhibernate.SimpleHibernateDemo.Person"
        table="Person">
        <cache usage="read-write" />

        <id name="id" column="id">
            <generator class="native" />
        </id>

        <property name="name">
            <column name="name" length="24" not-null="true" />
        </property>
        <property name="surname">
            <column name="surname" length="36"></column>
        </property>
        <property name="address">
            <column name="address" length="32"></column>
        </property>
        <joined-subclass name="com.masterhibernate.SimpleHibernateDemo.Parent"
            table="Parent">
            <key column="person_id" foreign-key="parent_person" />
            <property name="job" column="WorkPlace" length="22" type="string" />
            <set name="children" inverse="true" cascade="save-update" lazy="true">
                <cache usage="read-write" />
                <!-- specifies foreign key column of child table -->
                <key column="ParentPK" />
                <one-to-many class="com.masterhibernate.SimpleHibernateDemo.Child" />
            </set>
        </joined-subclass>
        <joined-subclass name="com.masterhibernate.SimpleHibernateDemo.Child"
            table="Child">
            <key column="person_id" foreign-key="child_person" />
            <property name="toy" column="toy" length="55" type="string" />
            <many-to-one name="parent"
                class="com.masterhibernate.SimpleHibernateDemo.Parent" column="ParentPK"
                lazy="false" fetch="join" foreign-key="child_parent" />
            <set name="teachers" table="TeacherPupil" inverse="true" lazy="true">
                <key column="child_id" foreign-key="teacherPupil_child" />
                <many-to-many class="com.masterhibernate.SimpleHibernateDemo.Teacher"
                    column="teacher_id" />
            </set>
        </joined-subclass>
        <joined-subclass name="com.masterhibernate.SimpleHibernateDemo.Teacher"
            table="Teacher">
            <key column="person_id" foreign-key="teacher_person" />
            <property name="subject" column="subject" length="25" type="string" />
            <set name="children" table="TeacherPupil" lazy="false" fetch="join">
                <cache usage="read-write" />
                <key column="teacher_id" foreign-key="teacherPupil_teacher" />
                <many-to-many class="com.masterhibernate.SimpleHibernateDemo.Child"
                    column="child_id" />
            </set>
            <map name="childByName" table="Child_By_Name" embed-xml="true">
                <key column="childByName_id" />
                <index column="childName" type="string" />
                <one-to-many class="com.masterhibernate.SimpleHibernateDemo.Child" />
            </map>
        </joined-subclass>
    </class>
</hibernate-mapping>

不幸的是&lt;map&gt; 甚至没有创建名为Child_By_Name 的单独表。相反,它在表Child 中创建列childByNamechildName。这很奇怪。

那么,如何将我的 childByName 映射映射到单独的表中以引用 Child 作为其值?

【问题讨论】:

    标签: java hibernate jpa orm hibernate-mapping


    【解决方案1】:

    既然您已经有一个 TeacherPupil 表,您也应该将它用于您的地图关联:

    <map name="childByName" table="TeacherPupil" inverse="true">
    
    <key column="teacher_id" not-null="true"/>
    
    <map-key-many-to-many column="name" class="Child"/>
    
    <many-to-many class="Child"/>
    
    </map>
    

    【讨论】:

    • 请看我的完整版Person.hbm.xml。它也有 Child 的映射
    • 集合和地图都针对相同的关联,所以也许你应该用地图替换集合,如果老师处理关联,则删除逆真属性。
    • 谢谢!我试试这个
    【解决方案2】:

    我很欣赏所有的答案,但你可以做的另一件事是, 创建一个实体:

    @Entity
    @XmlRootElement(name = "ChildName")
    @Table(name="ChildName")
    public class ChildName{
    @Id
    private Long  id;
    private String name;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "childId")
    private Child child;
    

    }

    加入你的专栏

    @Entity
    @XmlRootElement(name = "Teacher")
    @Table(name="Teacher")
    public class Teacher {
    
    @Id
    private Long id;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "childNameId")
    private ChildName childName;
    

    }

    你的整个代码都会喜欢

    @Entity
    @XmlRootElement(name = "Teacher")
    @Table(name="Teacher")
    public class Teacher {
    
    @Id
    private Long id;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "childNameId")
    private ChildName childName;
    

    }

    @Entity
    @XmlRootElement(name = "ChildName")
    @Table(name="ChildName")
    class ChildName{
    @Id
    private Long  id;
    private String name;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "childId")
    private Child child;
    

    }

    @Entity
    @XmlRootElement(name = "Child")
    @Table(name="Child")
    public class Child extends Person implements Serializable {
    

    }

    @Entity
    @XmlRootElement(name = "Person")
    @Table(name="Person")
    public class Person implements Serializable {
    @Id
    private Long id;
    private String name;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    

    }

    这不是地图关联,它会像那样工作

    【讨论】:

    • 为什么会有@XmlRootElement注解?
    • 将类或枚举类型映射到 XML 元素。用法 @XmlRootElement 注解可用于以下程序元素:顶级类、枚举类型stackoverflow.com/questions/11520724/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-13
    • 1970-01-01
    相关资源
    最近更新 更多