2011-07-29 59 views
3

我是Hibernate的新手。在我的情况下,我有一个具有包含连接ID到许多其他表的记录的具体表 - 都具有相同的结构。 我想达成的目标是得到这样的Hibernate继承和多个表具有相同的类

SELECT * 
    FROM main_records mr, ref1 r1, ref2 r2 
WHERE r1.id = mr.id_ref1 
    AND r2.id = mr.id_ref2; 

主要的想法是重用类所有连接引用。

SQL

CREATE TABLE main_records 
(
    id integer NOT NULL, 
    id_ref1 integer NOT NULL, 
    id_ref2 integer NOT NULL 
)  
CREATE TABLE ref1 
(
    id integer NOT NULL, 
    value character varying 
) 
CREATE TABLE ref2 
(
    id integer NOT NULL, 
    value character varying 
) 

我设置基础POJO类

Java类

public class MainRecord { 
    private Integer id; 
    private Ref ref1; 
    private Ref ref2; 
    ... 
    // getters and setters 
} 

public class Ref { 
    private Integer id; 
    private String value; 
    ... 
    // getters and setters 
} 

我的想法是在下面的方式来定义的Hibernate映射:

定义一个抽象超类

<hibernate-mapping package="test"> 
    <class abstract="true" name="Ref"> 
     <id name="id" type="java.lang.Integer" column="ID"> 
      <generator class="native" /> 
     </id> 
     <property name="value" type="java.lang.String" column="VALUE" /> 
    </class> 
</hibernate-mapping> 

地图的主要实体,扩展了超类,但使用单独的表

<hibernate-mapping package="test"> 
    <union-subclass name="Ref1" table="REF1" extends="Ref" /> 
    <union-subclass name="Ref2" table="REF2" extends="Ref" /> 

    <class name="MainRecord" table="MAIN_RECORDS"> 
     <id name="id" column="ID" type="java.lang.Integer" /> 
     <many-to-one name="ref1" class="Ref1" column="ID_REF1" fetch="join" unique="true" /> 
     <many-to-one name="ref2" class="Ref2" column="ID_REF2" fetch="join" unique="true" /> 
    </union-subclass> 
    </class> 
</hibernate-mapping> 

我手动包括在配置映射文件,加载似乎确定但随后出现错误,没有任何详细说明:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.apache.cxf.transport.servlet.ServletTransportFactory' defined in class path resource [META-INF/cxf/cxf-servlet.xml]: Error setting property values; 
nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (2) are: 
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'bus' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/spring/database.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer] 
PropertyAccessException 2: org.springframework.beans.MethodInvocationException: Property 'transportIds' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/spring/database.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1361) 

该系统是Spring 2.5中的一个组合,具备Hibernate 3.2 CXF 2.3.4,Javassist是3.11,

我的问题是:

(一)这是正确的做法?

(B),只要我介绍

<union-subclass name="Ref1" table="REF1" extends="Ref" /> 
<union-subclass name="Ref2" table="REF2" extends="Ref" /> 

,所以我想这是不是做的最好的方式出现的错误?

(c)它可以用注释书写吗?我无法理解如何定义Ref1和Ref2类,而无需为它们创建POJO类。 (d)我可以使用多于一级的继承吗?例如,我想为我所有的具体表格使用一个抽象超类,它们涵盖了它们都有的共同审计领域? 让我们假设类Ref在Java和Hibernate映射中扩展了抽象AuditTable类。

回答

1

如果我理解正确的问题,你有多个外键来了很多表的有彼此相同colums主记录表?

(一)这是正确的做法?

不,您试图通过使用Table per class战略来实现继承,因为您对每个类型对象都有一个引用(场中的Ref1和字段Ref2) )。 可以适当使用继承的使用情况是,如果你有一个多态型的关联在MasterRecord对象REF

的多态关联的实施例为ref

public class MasterRecord{ 

    Long id; 

    Ref anyObjectRef1OrRef2; <-- Polymorphic association 
} 

关联anyObjectRef1OrRef2本来地图MasterRecord的映射中有<any ... />元素。它会需要两列的一个与类名和一个用于外键

(B),所以我想这是不是做的最好的办法,只要我介绍<union-subclass出现的错误......?

你应该做的是从超(无特定表这个超类)继承性

(C)将其与注解写?

是使用@MappedSuperclass注解。
Hibernate参考实现(使用注释)

(C-A)我无法捉摸如何定义REF1和REF2类,而实际上 为他们创造一个POJO类?

不创建Ref1和Ref2 pojo类就无法完成。

(d)我可以使用多于1级的继承吗?例如,我希望 对我所有的具体表格使用抽象超类,它们涵盖了它们都有的共同审计字段?比方说,类参考扩展 抽象AuditTable

例与注释

基类Ref.java

@MappedSuperclass 
public abstract class Ref { 

    String value; 

} 

类Ref1.java

@Entity 
public class Ref1 extends Ref { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    Long id; 
} 

类Ref2.java

@Entity 
public class Ref2 extends Ref { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    Long id; 
} 

类MainRecord.java

@Entity 
public class MainRecord { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    Long id; 

    @ManyToOne(cascade=CascadeType.ALL, targetEntity=Ref1.class)  
    Ref ref1; 

    @ManyToOne(cascade=CascadeType.ALL, targetEntity=Ref2.class) 
    Ref ref2; 
} 

创建并保存实体遵循

..begin transaction 

MainRecord mainRecord = new MainRecord(); 

Ref1 ref1 = new Ref1(); 
ref1.setValue("tettset"); 

Ref2 ref2 = new Ref2(); 
ref2.setValue("tettset"); 

mainRecord.setRef2(ref2); 
mainRecord.setRef1(ref1); 

entitymanager.persist(mainRecord); 

..commit transaction. 

使用Hibernate马平的文件,你需要删除所有注释使用映射如下。

不是说,当使用映射文件时,抽象的Ref.java超类未映射,超类的所有属性都在每个子映射文件中。

<class name="MainRecord" table="MAIN_RECORDS"> 
     <id name="id" column="uid" type="long"> 
       <generator class="identity"/> 
     </id> 
     <many-to-one name="ref1" class="Ref1" column="ID_REF1" fetch="join" unique="true" cascade="all" />   
     <many-to-one name="ref2" class="Ref2" column="ID_REF2" fetch="join" unique="true" cascade="all" />  

</class> 

<class name="Ref1" table="REF1"> 
     <id name="id" column="uid" type="long"> 
       <generator class="identity"/> 
     </id> 
     <property name="value" type="java.lang.String" column="VALUE" /> 
</class> 

<class name="Ref2" table="REF2"> 
     <id name="id" column="uid" type="long"> 
       <generator class="identity"/> 
     </id> 
     <property name="value" type="java.lang.String" column="VALUE" /> 
</class> 
+0

感谢这个例子,进入了这个方向bot进入了新的麻烦。更多细节在这里http://stackoverflow.com/questions/7105832/hibernate-throws-wrongclassexception-for-a-simple-foreign-key – Andraz

0

只有一个问题....如果您使用相同的类访问多个不同的表... 要保存哪些表将保存新的实例? Hibernate将如何知道?

AFAIK,这是不能做到的。

+0

Shuldn​​'t通过Ref1和Ref2类解决?他们有正确的表格定义。类Ref仅用于字段映射。 – Andraz

0

这些快捷方式,即使它们可以开始工作,也往往会导致继承代码的开发人员最终混淆的道路。在你问“是否可以完成”之前,问“是否应该完成”。想一想:通过创建更少的类并使用某种模糊的特性,在开发时更加“高效”,还是仅仅让单独的类变得更容易理解,会更好一些。此外,您可能框自己陷入了困境,因为这种特定的功能可能会导致意想不到的后果,经典的“为什么是这样做”的局面。

我继承了许多应用程序,其中的开发商上代想干的事在“凉”或“优雅”的方式,最终造成比,如果他们把每一件事情具体,简单的更多的混乱。

只需创建单独的类。

相关问题