一个实体类映射几个表

时间:2012-10-30 13:21:53

标签: java hibernate jpa orm

我的项目中有一个非常重要的表 - 强制表。它有几列,但在这种情况下,最重要的是主键。

Mandatory
1. id (Long Primary Key)
...

现在我必须添加两个新表 - 附加表和额外表。它们都只有两列。另外两者都是主键。你可以看到其中一个也是外键。

Additional
1. mandatory_id (Long Primary Key FK -> Mandatory.id)
2. description (Varchar(512) Primary Key)

在Extra表中,主键也是外键。

Extra
1. mandatory_id (Long Primary Key FK -> Mandatory.id)
2. text (Varchar(512) 

我正在考虑如何在使用Hibernate的项目中实现它。

我已经用这种方式声明了它们(这里没有getter,setter等),MandatoryEntity class:

@Entity
@Table(name = "mandatory")
public class MandatoryEntity {

    @OneToMany
    @JoinColumn(name = "mandatory_id")
    protected List<AdditionalEntity> additonals;

    @OneToOne
    @JoinColumn(name = "mandatory_id")
    protected ExtraEntity extra;
}

AdditionalEntity上课:

@Entity
@Table(name = "additional")
public class AdditionalEntity {

    @EmbeddedId
    private AdditionalPK id;

    @ManyToOne(fetch = FetchType.LAZY)
    @Fetch(value = FetchMode.JOIN)
    @JoinColumn(name = "mandatory_id", nullable = false, insertable = false, updatable = false)
    protected MandatoryEntity mandatory;
}

AdditionalPK上课:

@Embeddable
public class AdditionalPK {

    @Column(name = "mandatory_id")
    private Long mandatoryId;

    @Column(name = "description")
    private String description;
}

ExtraEntity上课:

@Entity
@Table(name = "extra")
public class ExtraEntity {

    @Id
    @Column(name = "mandatory_id")
    private Long id;

    @OneToOne 
    @PrimaryKeyJoinColumn
    protected MandatoryEntity mandatory

    @Column(name = "text")
    protected String text;
}

此时,我工作的笔记本电脑坏了,所以我有时间考虑。我在JPA Specification @SecondaryTables注释中找到了。我可以在我的案例中使用这个注释吗?这些只有两个表,每个表只有两列。第一个是复合主键,第二个没有。

也许还有另一种方法可以在一个MandatoryEntity中实现这些表格?没有两个新实体:AdditionalEntityExtraEntity

1 个答案:

答案 0 :(得分:1)

首先,让我根据您的要求重新理解我的理解。

  1. 您有一个主要实体(必填)
  2. 您还有两个其他实体为强制实体指定了其他信息。其中

    一个。可以指定多个附加信息(ManyToOne)

    湾可以指定一个额外信息(OneToOne)

  3. 通常这是一个非常基本的用例。您必须决定的是,您是需要双向映射还是单向映射(仅通过强制实体访问)就足够了。我希望单向映射对于您的用例来说是一个不错的选择,因为似乎Mandatory是您的根实体。在您的代码中,您尝试建模双向关系但忘记指定反向关系。这实际上会导致两个独立的关系。您应该指定双向关系的目标,如下所示:

    
    @Entity
    @Table(name = "mandatory")
    public class MandatoryEntity {
        // you need a mapped by to mark the relation as bidirectional
        @OneToMany(mappedBy = "mandatory")
        protected List additonals;
        @OneToOne
        protected ExtraEntity extra;
    }

    @Entity @Table(name = "additional") public class AdditionalEntity { @EmbeddedId private AdditionalPK id; @ManyToOne(fetch = FetchType.LAZY) protected MandatoryEntity mandatory; }

    您还指定了许多其他映射信息,这些信息在您的示例中不需要,这使得一切看起来都太复杂了。也 你为什么使用嵌入式密钥?我认为自动生成的密钥对你也有用。我对你的模型的建议如下:

    
    @Entity
    @Table(name = "mandatory")
    public class MandatoryEntity {
        @Id
        @GeneratedValue(strategy =  GenerationType.AUTO)
        private Long id;
    // you need a mapped by to mark the relation as bidirectional
        @OneToMany(mappedBy = "mandatory")
        protected List additonals;
        @OneToOne
        protected ExtraEntity extra;
    }
    @Entity
    @Table(name = "additional")
    public class AdditionalEntity {
        @Id
        @GeneratedValue(strategy =  GenerationType.AUTO)
        private Long id;
        @ManyToOne(fetch = FetchType.LAZY)
        protected MandatoryEntity mandatory;
    }
    @Entity
    @Table(name = "extra")
    public class ExtraEntity {
        // you might also not use auto-value here and set the id to the id of the owning
        // mandatory entity
        @Id
        @GeneratedValue(strategy =  GenerationType.AUTO)
        private Long id;
        @Column(name = "text")
        protected String text;
    }
    

    如果我遗漏了一些要求并且我建议的映射在您的情况下不起作用,那么请添加有关您的要求的更多信息,我们可以进一步讨论。