1

私はJavaとHibernateを初めて使用します(ただし、Entity Frameworkに精通しているため、多くの概念を理解しています)

私がやりたいOrganisationNodeのは、次のフィールドを持つテーブルをId作成Nameすることだけです。ParentId

ParentIdはNull可能であり、存在する場合は、有効なを指す必要がありますOranisationNode.Id

これはかなり単純なはずだと思いましたが、XMLファイルのグーグルと編集に2日以上費やしたため、忍耐力を失い始めています。

コードスニペットから始めましょう...

OrganisationNode.java

@javax.persistence.Entity
public class OrganisationNode extends EntityBase implements Serializable {
    private String name;

    @ManyToOne(targetEntity = OrganisationNode.class, optional = true)
    @JoinColumn(name="ParentId", referencedColumnName="Id") //This is one example of this attribute. I've tried many combinations
    private OrganisationNode parent;

    @OneToMany
    private Set<OrganisationNode> children = new HashSet<OrganisationNode>();

    //Getters/Setters
}

EntityBase.java

@javax.persistence.Entity
public class EntityBase implements Serializable {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    //Getter/Setter
}

Hibernate.config.xml

<!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.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://mysqldev:3306/SomeDb?zeroDateTimeBehavior=convertToNull</property>
    <property name="hibernate.connection.username">SomeUser</property>
    <property name="hibernate.connection.password">SomePass!</property>
    <property name="hibernate.hbm2ddl.auto">create</property>
    <property name="show_sql">true</property>
    <mapping resource="hibernate.hbm.xml"/>
  </session-factory>
</hibernate-configuration>

Hibernate.hbm.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.overshare.document.entities.OrganisationNode" table="OrganisationNodes">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
        <property name="children"/>
        <property name="parent"/>
    </class>
</hibernate-mapping>

HibernateUtil.java

public class HibernateUtil {

    private static SessionFactory sessionFactory;

    public static void configureSessionFactory() {

            Configuration configuration = new Configuration();
            configuration.configure("hibernate.cfg.xml");
            ServiceRegistryBuilder serviceRegistryBuilder = new ServiceRegistryBuilder().applySettings(configuration.getProperties());
            sessionFactory = configuration.buildSessionFactory(serviceRegistryBuilder.buildServiceRegistry());
    }

    public static SessionFactory getSessionFactory() {
        if(sessionFactory == null){configureSessionFactory();}
        return sessionFactory;
    }
}

私が現在得ている例外は...

javax.servlet.ServletException:org.hibernate.MappingException:次のタイプを判別できませんでした:java.util.Set、テーブル:OrganisationNodes、列:[org.hibernate.mapping.Column(Children)]

だから、私の最初の質問は、どうすればこの例外を解決できますか?Children何を指しているべきかを明確に伝えたと思います。

私の次の質問は...これは本当に必要ですか?単一のテーブルをORMで起動して実行するには、非常に多くの構成とコードが必要になるとは信じがたいです。私がここで得たもののほとんどは、Web上のさまざまな例からハッキングされているため、品質がわかりません。確かに、この情報の90%は、リフレクションを介して休止状態に利用できる必要がありますか?

4

2 に答える 2

3

ここでは、xmlマッピングとアノテーションを混合しています。あなたの場合、注釈だけで十分です。まず、Hibernate.hbm.xmlを削除します。

OrganisationNode.java

@Entity
public class OrganisationNode extends EntityBase {

    private String name;
    private String description;

    @ManyToOne
    @JoinColumn(name="ParentId")
    private OrganisationNode parent;

    @OneToMany
    private Set<OrganisationNode> children = new HashSet<OrganisationNode>();

}

EntityBase.java

@Entity
public class EntityBase {
    @Id
    @GeneratedValue
    private Long id;

}

Hibernate.config.xml

<!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.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://mysqldev:3306/SomeDb?zeroDateTimeBehavior=convertToNull</property>
    <property name="hibernate.connection.username">SomeUser</property>
    <property name="hibernate.connection.password">SomePass!</property>
    <property name="hibernate.hbm2ddl.auto">create</property>
    <property name="show_sql">true</property>

    <mapping class="com.overshare.document.entities.OrganisationNode"/>
  </session-factory>
</hibernate-configuration>
于 2013-02-25T16:15:13.997 に答える
1

「Hibernate.hbm.xml」を使用するか、アノテーションを使用する必要があります。あなたは両方を使おうとしていますが、それは混乱を招く休止状態だと思います。

「Hibernate.hbm.xml」で行っていることはすべて、代わりにアノテーションとしてエンティティークラスに入れることができます。これにより、作業がはるかに簡単になります。

@Entity
@Table(name = "OrganisationNodes")
public class OrganisationNode implements Serializable {
    @Column(name = "NAME")
    private String name;

    @Column(name = "DESCRIPTION")
    private String description;
    etc.

私も取り除くでしょうEntityBase。見た目ではあまり意味がなく、Hibernateで基本クラスを拡張するのは面倒な場合があります。

于 2013-02-25T16:15:14.460 に答える