Hibernate Discriminator

时间:2013-09-04 15:56:31

标签: java hibernate hibernate-mapping discriminator

我有类似的东西

table ACTION
name
resource_type
resource_id

resource_type和resource_id用于区分资源类型:

resource_type可以是imagevideo,如果resource_type包含image,则resource_id是表IMAGE的id;如果resource_type包含video,则resource_id是表VIDEO的id

此处有IMAGE和VIDEO表格

table IMAGE (*)
id 
imageType

table VIDEO (*)
id
videoType

(*)表格更复杂,但为了更好的解释,我缩减了它!

我也有以下课程

class Action{
    private Resource resource;
    //getter and setter
}

interface Resource{}

class Image implements Resource{
    private Integer id;
    private String imageType;
    //getter and setter
}

class Video implements Resource{
    private Integer id;
    private String videoType;
    //getter and setter
}

我试图从本教程中了解一些有关discriminator属性的内容: http://viralpatel.net/blogs/hibernate-inheritence-table-per-hierarchy-mapping/ 但是例子有点不同......-_-'

我想在Action类的Resource对象中映射IMAGE end VIDEO表,我如何用hibernate xml mapper映射这些pojo类???

1 个答案:

答案 0 :(得分:2)

您不需要使用鉴别器。您可以使用“每类表”方法继承。这是你做的。

  1. 定义具有“id”属性(即id)的“资源”类。
  2. 定义两个子类,“图像”和“视频”,用于扩展资源并添加其他属性 - 在您的示例中,“imageType”和“videoType”。
  3. 将具有@ManyToOne的类“Action”定义为Resource。如果您想要在帖子中描述的“resourceType”属性,您可以拥有它,但完全没必要让事情发挥作用。
  4. 我不确定你想要什么类型的id生成(如果有的话)或者从Action to Resource到什么类型的级联,所以为了简单起见,我假设没有这两种类型。
  5. 使用这种方法,您将在数据库中获得3个表。

    以下是实现的shell:

    @Entity 
    @Inheritance (strategy=InheritanceType.TABLE_PER_CLASS)
    public abstract class Resource {
    
        @Id
        @Column(name="ID")
        private String id;
    
        public Resource() {}
        public Resource(String id)  { this.id = id;  }
        ... // getters and setters
    }
    
    @Entity
    
    /* Table per Concrete Class */
    @Table (name="Image") 
    public class Image extends Resource {
    
        private String imageType;  // Other properties unique to Image
    
        public Image() {}
        public Image(String id) { super(id); }
        public Image(String id, ...) { super(id); .... // setters }
        ... // getters and setters
    }
    
    /* Table per Concrete Class */
    @Table (name="Video") 
    public class Video extends Resource {
    
        private String videoType;   // Other properties unique to Video
        public Video() {}
        public Video(String id) { super(id); }
        public Video(String id, ...) { super(id); .... // setters }
        ... // getters and setters
    }
    

    使用这种方法,以下单元测试显示了所需的行为:

    Image image = new Image("i1", "imageType");
    Video video = new Video("v1", "videoType");
    
    Action imageAction = new Action("imageAction", image, "image");
    Action videoAction = new Action("videoAction", video, "video");
    
    manager.persist(image);
    manager.persist(video);
    manager.persist(imageAction);
    manager.persist(videoAction);
    manager.getTransaction().commit();
    
    ...
    
    
    manager.getTransaction().begin();
    
    System.out.println("********** Actions and Resources");
    List<Action> result1 = manager.createQuery( "from Action" ).getResultList();
    for ( Action a : result1 ) {
        System.out.println(a);
    }
    manager.getTransaction().commit();
    

    为所有这些类实现toString(),产生以下输出:

    Hibernate:create table Action(NAME varchar(255)not null,RESOURCE_TYPE varchar(255),RESOURCE_ID varchar(255),primary key(NAME)) Hibernate:创建表Image(ID varchar(255)not null,imageProperty varchar(255),主键(ID)) Hibernate:创建表视频(ID varchar(255)not null,videoProperty varchar(255),主键(ID))

    **** 操作和资源 Action(name = imageAction resource = Image(id = i1 imageType = imageType)resourceType = image) 操作(name = videoAction resource = Video(id = v1 videoType = videoType)resourceType = video)

    希望这有助于回答您的问题。

    萨拉