0

私は Hibernate を使用するのは初めてですが、仕事中のプロジェクトに使用する必要があります。Derby Embedded で Netbeans を使用していますが、別の IDE に変更することはできません。

私が抱えている問題は、データベース内の多対多の関係に関連しています。

テーブル PROBLEM、テーブル MACHINE、ジャンクション テーブル MACHINEPROBLEM があります。Problem には多くのマシンを含めることができ、Machine には多くの問題を含めることができます。これらのテーブルは、ジャンクション テーブル MACHINEPROBLEM によって関連付けられています。

必要な POJO とマッピング ファイル (適切に hibernate.cfg.xml で参照) を用意し、Netbeans と Hibernate がデータベースにテーブルを自動的に作成するようにします。テーブルとそれぞれの関係が正しく作成されました。テーブル MACHINEPROBLEM には、MACHINE テーブルの「id」を参照する「machineid」と、PROBLEM テーブルの「id」を参照する「problemid」で構成される複合キーがあります。

問題オブジェクトを作成し、マシンのセットを追加してデータベースに保存すると、ジャンクション テーブルにデータが入力されません。データは PROBLEM テーブルと MACHINE テーブルの両方に正しく保存されますが、MACHINEPROBLEM テーブルは空です。これは、マシンを接続するために使用されるジャンクション テーブルが空であるため、特定の問題のすべてのマシンを検索できないことを意味します。

誰でもこの問題を解決するのを手伝ってもらえますか? ありがとう。


マッピング ファイル:

Machine.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="DataAccess.entity.Machine" table="MACHINE" schema="APP">
        <id name="id" type="long">
            <column name="ID" />
            <generator class="assigned" />
        </id>
        <set name="problems" inverse="false" lazy="true" fetch="select" table="MACHINEPROBLEM">
         <key column="MACHINEID"/>
         <many-to-many column="PROBLEMID" class="DataAccess.entity.Problem"/>
        </set>
        <property name="machineid" type="string">
            <column name="MACHINEID" length="10" not-null="true" />
        </property>
    </class>
</hibernate-mapping>



問題.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="DataAccess.entity.Problem" table="PROBLEM" schema="APP">
        <id name="id" type="long">
            <column name="ID" />
            <generator class="assigned" />
        </id>
        <set name="machines" inverse="true" lazy="true" fetch="select" cascade="all" table="MACHINEPROBLEM">
         <key column="PROBLEMID"/>
         <many-to-many column="MACHINEID" class="DataAccess.entity.Machine"/>
        </set>
        <property name="problemid" type="string">
            <column name="PROBLEMID" length="10" not-null="true" />
        </property>
        <property name="problemname" type="string">
            <column name="PROBLEMNAME" length="50" not-null="true" />
        </property>
        <property name="tipoproblema" type="string">
            <column name="TIPOPROBLEMA" length="50" />
        </property>
        <property name="linear" type="boolean">
            <column name="LINEAR" not-null="true" />
        </property>
        <property name="numtarefas" type="int">
            <column name="NUMTAREFAS" not-null="true" />
        </property>
        <property name="nummaquinas" type="int">
            <column name="NUMMAQUINAS" not-null="true" />
        </property>
    </class>
</hibernate-mapping>



POJO:

Machine.java

public class Machine  implements java.io.Serializable {


     private long id;
     private String machineid;
     private Set<Problem> problems = new HashSet<Problem>();

    public Machine() {
    }

    public Machine(long id, String machineid) {
       this.id = id;
       this.machineid = machineid;
    }

    public long getId() {
        return this.id;
    }

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

    public String getMachineid() {
        return this.machineid;
    }

    public void setMachineid(String machineid) {
        this.machineid = machineid;
    }

     public Set<Problem> getProblems() {
      return problems;
    }

    public void setProblems( Set<Problem> problems ) {
      this.problems = problems;
     }

    public boolean equals(Object obj) {
      if (obj == null) return false;
      if (!this.getClass().equals(obj.getClass())) return false;

      Machine obj2 = (Machine)obj;
      if((this.id == obj2.getId()) && (this.machineid.equals(obj2.getMachineid())))
      {
         return true;
      }
      return false;
    }

    public int hashCode() {
       int tmp = 0;
       tmp = ( id + machineid ).hashCode();
       return tmp;
    }
}



問題.java

public class Problem  implements java.io.Serializable {


     private long id;
     private String problemid;
     private String problemname;
     private String tipoproblema;
     private boolean linear;
     private int numtarefas;
     private int nummaquinas;
     private Set<Machine> machines = new HashSet<Machine>();

    public Problem() {
    }


    public Problem(long id, String problemid, String problemname, boolean linear, int numtarefas, int nummaquinas) {
        this.id = id;
        this.problemid = problemid;
        this.problemname = problemname;
        this.linear = linear;
        this.numtarefas = numtarefas;
        this.nummaquinas = nummaquinas;
    }

    public Problem(long id, String problemid, String problemname, String tipoproblema, boolean linear, int numtarefas, int nummaquinas) {
       this.id = id;
       this.problemid = problemid;
       this.problemname = problemname;
       this.tipoproblema = tipoproblema;
       this.linear = linear;
       this.numtarefas = numtarefas;
       this.nummaquinas = nummaquinas;
    }

    public long getId() {
        return this.id;
    }

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

    public String getProblemid() {
        return this.problemid;
    }

    public void setProblemid(String problemid) {
        this.problemid = problemid;
    }

    public String getProblemname() {
        return this.problemname;
    }

    public void setProblemname(String problemname) {
        this.problemname = problemname;
    }

    public String getTipoproblema() {
        return this.tipoproblema;
    }

    public void setTipoproblema(String tipoproblema) {
        this.tipoproblema = tipoproblema;
    }

    public boolean isLinear() {
        return this.linear;
    }

    public void setLinear(boolean linear) {
        this.linear = linear;
    }

    public int getNumtarefas() {
        return this.numtarefas;
    }

    public void setNumtarefas(int numtarefas) {
        this.numtarefas = numtarefas;
    }

    public int getNummaquinas() {
        return this.nummaquinas;
    }

    public void setNummaquinas(int nummaquinas) {
        this.nummaquinas = nummaquinas;
    }

    public Set<Machine> getMachines() {
      return machines;
    }

    public void setMachines( Set<Machine> machines ) {
      this.machines = machines;
     }
}



メインクラス:

public class Test {

    public static void main(String[] args) {    

        try
        {
             //Adds a couple of machines to a hashset
             Set<Machine> machines = new HashSet<>();
             machines.add(new Machine(1, "M1"));
             machines.add(new Machine(2, "M2"));

             //creates a Problem with some random data
             Problem p = new Problem(2, "OSD1", "TestP", "jobshop", true, 2, 3);    
             p.setMachines(machines);

             //Adds Problem p to the database
             ProblemDAL pDal = new ProblemDAL(null); 
             pDal.add(p); //Doing this saves Problem p to table PROBLEM, as well as the set of machines to table MACHINE. However, nothing's saved in the junction table MACHINEPROBLEM.

             pDal.closeSession();
        }
        catch (Exception e){
            e.printStackTrace();
        }

    }
}



問題DAL

public class ProblemDAL {
    Session session;
    boolean closeSession;

    public ProblemDAL(Session session)
    {
        if(session == null)
        {
            this.session = HibernateUtil.getSessionFactory().openSession();
        }
        else
        {
            this.session = session;
        }        
    }

    public void add(Problem entity) throws Exception {
        Transaction tx = null;

        try {
            tx = session.beginTransaction();
            session.save(entity);
            tx.commit();
        } 
        catch (HibernateException e) {
            if (tx!=null) tx.rollback();
            e.printStackTrace(); 
        } 
    }

    public void update(Problem entity)
    {
        Transaction tx = null;

        try {            
            tx = session.beginTransaction();
            session.update(entity);
            tx.commit();
        }
        catch (HibernateException e) {
            if (tx!=null) tx.rollback();
            e.printStackTrace(); 
        } 
    }

    public void delete(Problem entity){
        Transaction tx = null;

        try{
           tx = session.beginTransaction();         
           session.delete(entity); 
           tx.commit();
        }
        catch (HibernateException e) {
           if (tx!=null) tx.rollback();
           e.printStackTrace(); 
        }
    }



    public Problem getById(long id) {
        Transaction tx = null;
        Problem entity = null;

        try {
            tx = session.beginTransaction();
            entity = (Problem) session.get(Problem.class, id);
            tx.commit();   
        }
        catch (HibernateException e) {
            if (tx!=null) tx.rollback();
            e.printStackTrace(); 
        }
        finally {
            return entity;
        }

    }



    public List<Problem> getAll() {
        Transaction tx = null;
        List<Problem> entityList = null;

        try {
            tx = session.beginTransaction();
            entityList = session.createQuery("from Problem").list();
            tx.commit();             
        }
        catch (HibernateException e) {
            if (tx!=null) tx.rollback();
            e.printStackTrace(); 
        }
        finally {
            return entityList;
        }
    }

    public List<Machine> getMachines() {
        Transaction tx = null;
        List<Machine> entityList = null;

        try {
            tx = session.beginTransaction();
            entityList = session.createQuery("select machines from Problem").list();
            tx.commit();             
        }
        catch (HibernateException e) {
            if (tx!=null) tx.rollback();
            e.printStackTrace(); 
        }
        finally {
            return entityList;
        }
    }

    public void closeSession()
    {
        if(this.session!=null)
        {
            this.session.close();
        }
    } 
}



hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.DerbyDialect</property>
    <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.EmbeddedDriver</property>
    <property name="hibernate.hbm2ddl.auto">update</property>
    <property name="hibernate.connection.url">jdbc:derby:DB;create=true</property>
    <property name="hibernate.connection.username">***</property>
    <property name="hibernate.connection.password">***</property>
    <property name="hibernate.show_sql">true</property>
    <mapping resource="DataAccess/entity/Problem.hbm.xml"/>
    <mapping resource="DataAccess/entity/Machine.hbm.xml"/>
    <mapping resource="DataAccess/entity/Operation.hbm.xml"/>
    <mapping resource="DataAccess/entity/EvaluationParameters.hbm.xml"/>
    <mapping resource="DataAccess/entity/Generatedjobs.hbm.xml"/>
    <mapping resource="DataAccess/entity/Jobs.hbm.xml"/>
  </session-factory>
</hibernate-configuration>
4

1 に答える 1

1

このような問題の最も一般的な問題は、関係の両側を設定していないことです。

現時点では Hibernate の問題を無視するのが最善の方法です。

あなたが考えるならば:

Problem p = new Problem();
Machine m = new Machine();
m.addProblem(p);

永続性の問題を無視すると、ドメイン モデルは一貫した状態になります。マシン「m」は問題「p」に関連付けられていますか? つまり、p.getMachines().contains(m) は true を返しますか?

したがって、通常はこれらの操作をカプセル化するのが最善です。

public class Machine{

public void addProblem(Problem p){
problems.add(p);
p.getMachines.add(this);
}


public class Problem{
public void addMachine(Machine m){
machines.add(m);
m.getProblems().add(this);
}

実験として、現在のコードを使用して、一連の問題を含む新しいマシンを保存することができます。Machine は所有 (非反転) 側であるため、結果は期待どおりになるはずです。

于 2013-11-08T09:31:08.727 に答える