【问题标题】:How to set up many to many relationship in hibernate using XML mapping如何使用 XML 映射在 hibernate 中建立多对多关系
【发布时间】:2013-07-27 22:38:09
【问题描述】:

我有以下情况:

我是 hibernate 新手,我有一个项目要在接下来的几天内完成。

这是关于 Java 中的 CRUD Web 应用程序。第一步已经完成,但我真的被卡住了,我在互联网上找不到任何关于以下情况的帮助:

我有一个项目表,它可以包含来自操作表的许多操作。 (多对多关系)。

我还有一个 Payments 表,它有一个主键 (paymentId) 和 Project 和 action 的 2 个外键 (projectId,actionId) 以及其他一些字段,如 paymentMethodprice、@987654325 @,endDate。我实际上使用 Payments 表将每个项目连接到每个操作,添加一些额外的信息,如金额等。

我希望我能澄清我对一般观点的看法。

我不知道我必须如何处理映射文件?我必须创建 2 个映射文件还是 3 个? (Project.hbm.xmlaction.hbm.xmlpayments.hbm.xml

一开始我想把关系分成以下几部分:

一个与支付有一对多关系的项目 POJO 类(映射 XML 将作为一对多的 1 关系)和一个与支付有多对一关系的动作 POJO 类(也与相关的 XML映射文件)。

还有一个带有支付的 POJO 类,包括 Objects Action 和 Projects,以及 XML 文件中相关的一对多关系。

我没有在任何教程中看到这样的实现,也没有在任何网站上看到这样的实现,我不知道这是否可以?

我发现的唯一一件事是使用注释的多对多关系(主要)和中间步骤表(在我的情况下为付款)只有 2 个外键,没有任何主键和像我这样的额外字段想要。

项目 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.nisid.entities.Project" table="projects">
      <meta attribute="class-description"> This class contains the project records. </meta> 
       <id name="projectId" type="int" column="projectId"> 
        <generator class="native">

        </generator> 
    </id> 

    <many-to-one name="fkCustomer" class="com.nisid.entities.Customers"
            fetch="select">
            <column name="customerId" not-null="true"/>
    </many-to-one>
      <set name="payments"  
            lazy="true" fetch="select" cascade="all">
          <key>
                <column name="projectId" />
            </key>


            <one-to-many class="com.nisid.entities.Payment" />
        </set>
 <property name="projectName" column="projectName" type="string"/> 
    <property name="projectDescription" column="description" type="string"/> 
   </class>
    </hibernate-mapping>

动作 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.nisid.entities.Action" table="actions" >
                <id name="actionId" type="int">
                    <column name="actionId" />
                    <generator class="native" >
                     </generator> 
                </id>
                <property name="actionName" type="string">
                    <column name="actionName"   />
                </property>

                <set name="payments" inverse="true" lazy="true" fetch="select">
                    <key>
                        <column name="actionId" />
                    </key>
                    <one-to-many class="com.nisid.entities.Payment" />
                </set>

            </class>
        </hibernate-mapping>

付款(映射xml):

<!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.nisid.entities.Payment" table="payments">


            <composite-id name="paymentId" class="com.nisid.entities.PaymentID" >

                <key-property name="myproject" column="projectId" />
                <key-property name="myaction" column="actionId" />

            </composite-id>

            <component name="myproject">

                <many-to-one name="project" class="com.nisid.entities.Project"
                    >
                    <column name="projectId" not-null="true" />
                </many-to-one>

            </component>

            <component name="myaction">

                <many-to-one name="action" class="com.nisid.entities.Action"
                    >
                    <column name="actionId" not-null="true" />
                </many-to-one>

            </component>


            <property name="amount" column="amount" type="int"/> 
            <property name="paymentDate" column="paymentDate" type="date"/> 
            <property name="paymentExpire" column="paymentExpire" type="date"/> 
            <property name="paymentMethod" column="paymentMethod" type="string"/>

        </class>

还有 ppojo 类:

行动:

/*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package com.nisid.entities;

    import java.util.HashSet;
    import java.util.Objects;
    import java.util.Set;

    /**
     *
     * @author p293
     */
    public class Action {

        private int actionId;
        private String actionName;
         private Set payments=new HashSet();



        public Action(){}

        public Action(String actionName) {
            this.actionName = actionName;
        }

        public int getActionId() {
            return actionId;
        }

        public void setActionId(int actionId) {
            this.actionId = actionId;
        }



        public String getActionName() {
            return actionName;
        }

        public void setActionName(String actionName) {
            this.actionName = actionName;
        }

        public Set getPayments() {
            return payments;
        }

        public void setPayments(Set payments) {
            this.payments = payments;
        }



        @Override
        public int hashCode() {
            int hash = 5;
            hash = 89 * hash + Objects.hashCode(this.actionName);
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Action other = (Action) obj;
            if (!Objects.equals(this.actionName, other.actionName)) {
                return false;
            }
            return true;
        }





        @Override
        public String toString() {
            return "Action{" + "=" + actionName + '}';
        }



    }

项目:

/*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package com.nisid.entities;

    import java.util.HashSet;
    import java.util.Objects;
    import java.util.Set;

    /**
     *
     * @author p293
     */
    public class Project {

        private int projectId;
        private String projectName;
        private String projectDescription;
        private Customers fkCustomer;
        private Set payments=new HashSet();

        public Project(){


        }

        public Project( String projectName, String projectDescription) {

            this.projectName = projectName;
            this.projectDescription = projectDescription;
        }


        public int getProjectId() {
            return projectId;
        }

        public void setProjectId(int projectId) {
            this.projectId = projectId;
        }

        public String getProjectName() {
            return projectName;
        }

        public void setProjectName(String projectName) {
            this.projectName = projectName;
        }

        public String getProjectDescription() {
            return projectDescription;
        }

        public void setProjectDescription(String projectDescription) {
            this.projectDescription = projectDescription;
        }

        public Customers getFkCustomer() {
            return fkCustomer;
        }

        public void setFkCustomer(Customers fkCustomer) {
            this.fkCustomer = fkCustomer;
        }

        public Set getPayments() {
            return payments;
        }

        public void setPayments(Set payments) {
            this.payments = payments;
        }








        @Override
        public int hashCode() {
            int hash = 7;
            hash = 79 * hash + Objects.hashCode(this.projectName);
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Project other = (Project) obj;
            if (!Objects.equals(this.projectName, other.projectName)) {
                return false;
            }
            return true;
        }


         @Override
        public String toString() {
            return "Project{" + "projectName=" + projectName + ",with description="    +       projectDescription + '}';
        }



    }

付款:

/*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package com.nisid.entities;

    import java.util.Date;
    import java.util.HashSet;
    import java.util.Objects;
    import java.util.Set;

    /**
     *
     * @author p293
     */
    public class Payment {

        private PaymentID paymentId=new PaymentID();
        private int amount;
        private Date paymentDate;
        private Date paymentExpire;
        private String paymentMethod;



        public Payment(int fkProjectId, int fkActionId, int amount, Date paymentDate, Date paymentExpire, String paymentMethod) {

            this.amount = amount;
            this.paymentDate = paymentDate;
            this.paymentExpire = paymentExpire;
            this.paymentMethod=paymentMethod;

        }

        public Payment(){}

        public PaymentID getPaymentId() {
            return paymentId;
        }

        public void setPaymentId(PaymentID paymentId) {
            this.paymentId = paymentId;
        }

        public int getAmount() {
            return amount;
        }

        public void setAmount(int amount) {
            this.amount = amount;
        }

        public Date getPaymentDate() {
            return paymentDate;
        }

        public void setPaymentDate(Date paymentDate) {
            this.paymentDate = paymentDate;
        }

        public Date getPaymentExpire() {
            return paymentExpire;
        }

        public void setPaymentExpire(Date paymentExpire) {
            this.paymentExpire = paymentExpire;
        }

        public String getPaymentMethod() {
            return paymentMethod;
        }

        public void setPaymentMethod(String paymentMethod) {
            this.paymentMethod = paymentMethod;
        }

        public Project getProject(){
            return getPaymentId().getProject();
        }

        public Action getAction(){
            return getPaymentId().getAction();
        }

        public void setAction(Action action){
            getPaymentId().setAction(action);
        }

        public void setProject(Project project){
            getPaymentId().setProject(project);
        }

        @Override
        public int hashCode() {
            int hash = 3;
            hash = 89 * hash + this.amount;
            hash = 89 * hash + Objects.hashCode(this.paymentMethod);
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Payment other = (Payment) obj;
            if (this.amount != other.amount) {
                return false;
            }
            if (!Objects.equals(this.paymentMethod, other.paymentMethod)) {
                return false;
            }
            return true;
        }




        @Override
        public String toString() {
            return "Payment{" + "amount=" + amount + ", paymentMethod=" + paymentMethod + '}';
        }




    }

付款 ID:

/*
         * To change this template, choose Tools | Templates
         * and open the template in the editor.
         */
        package com.nisid.entities;

        import java.util.Objects;

        /**
         *
         * @author lurtzaki
         */
        public class PaymentID {

            private Project myproject;
            private Action myaction ;

            public PaymentID(){
            super();}


            public Project getProject() {
                return myproject;
            }

            public void setProject(Project project) {
                this.myproject = project;
            }






    public Action getAction() {
                    return myaction;
                }
            public void setAction(Action action) {
                this.myaction = action;
            }

            @Override
            public int hashCode() {
                int hash = 3;
                hash = 17 * hash + Objects.hashCode(this.myproject);
                hash = 17 * hash + Objects.hashCode(this.myaction);
                return hash;
            }

            @Override
            public boolean equals(Object obj) {
                if (obj == null) {
                    return false;
                }
                if (getClass() != obj.getClass()) {
                    return false;
                }
                final PaymentID other = (PaymentID) obj;
                if (!Objects.equals(this.myproject, other.myproject)) {
                    return false;
                }
                if (!Objects.equals(this.myaction, other.myaction)) {
                    return false;
                }
                return true;
            }



        }

新的 XML:

<composite-id name="paymentId"         class="com.nisid.entities.PaymentID">
        <key-many-to-one name="myproject" class="com.nisid.entities.Project">
            <column name="projectId"/>
         </key-many-to-one>
         <key-many-to-one name="myaction" class="com.nisid.entities.Action">
            <column name="actionId" />
         </key-many-to-one>
    </composite-id>
    <property name="amount" column="amount" type="int"/> 
    <property name="paymentDate" column="paymentDate" type="date"/> 
    <property name="paymentExpire" column="paymentExpire" type="date"/> 
    <property name="paymentMethod" column="paymentMethod" type="string"/>

【问题讨论】:

  • 一个可以有很多动作的项目表不会是多对多的,除非这些动作也可以有很多项目。对此进行澄清可以帮助某人更好地回答这个问题。 mkyong.com/hibernate/…
  • 是的,这是真的。动作也可以有很多项目..所以多对多是双向关系是我的情况!

标签: xml hibernate many-to-many pojo xmlmapper


【解决方案1】:

如果您的付款表中需要paymentMethodpricestartDateendDate,那么您需要 3 个实体映射。您可以使用付款表作为其join table 来映射动作并相互投射多对多。或者,如果您在搜索 many to manyjoin table 的示例时遇到问题,您还可以为每个表操作和项目使用多对一来支付。

编辑:

先尝试测试project和payment,删除其他潜在的错误关系,如果成功了,可以实现到其他表。我的事情xml关系会是这样的:

project.hbm.xml中把一对多改成这样:

<list name="payments"
        inverse="true"
        cascade="save-update">
    <key column="projectId"/>
    <index column="actionId"/>
    <one-to-many class="Payment"/>
</list>

action.hbm.xml中把一对多改成这样:

<list name="payments"
        inverse="true"
        cascade="save-update">
    <key column="actionId"/>
    <index column="projectId"/>
    <one-to-many class="Payment"/>
</list>

payments.hbm.xml 中像这样(我的东西你不需要&lt;component&gt; 标记):

<hibernate-mapping>
    <class name="com.nisid.entities.Payment" table="payments">


        <composite-id name="paymentId" class="com.nisid.entities.PaymentID" >

            <key-property name="myproject" column="projectId" />
            <key-property name="myaction" column="actionId" />

        </composite-id>

        <many-to-one name="project" column="projectId" insert="false" update="false" not-null="true"/>
        <many-to-one name="action" column="actionId" insert="false" update="false" not-null="true"/>

        <property name="amount" column="amount" type="int"/> 
        <property name="paymentDate" column="paymentDate" type="date"/> 
        <property name="paymentExpire" column="paymentExpire" type="date"/> 
        <property name="paymentMethod" column="paymentMethod" type="string"/>

    </class>

【讨论】:

  • 嗨,我按照本教程进行操作mkyong.com/hibernate/…
  • 但我不知道为什么这不能播放..你能不能给我发任何完整的例子,比如上面的链接和一个使用 XML 映射的例子???
  • 您想以哪种方式读取值?也在这里发布您当前的 xml
  • 嗨,我将发布我拥有的所有 pojo 类和 XML,希望对您有所帮助。我想读取如下值:例如我有一个项目,每个项目都与操作表相关,每个项目还有价格、付款方式等(付款字段)
  • 嗨,对于支付表,我将复合键 {projectId,actionId} 作为主键,所以我不确定你上面所说的是否正确。为了测试你的建议,我必须更新我的数据库并使用只有 1 个 FK_key ( projectID) 和 paymentId 作为主键进行支付。除此之外,如果缺少 Action 表,我只需从项目-> 付款中进行一对多的实施!这与我必须做的不同
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-14
  • 2013-08-25
相关资源
最近更新 更多