@SecondaryTables:将一个实体映射到多个表

时间:2015-02-06 13:27:38

标签: hibernate postgresql

我非常清楚 @SecondaryTable 注释是将单个实体的 字段映射到多个表 ,就好像这些表合并为一个表一样 我在实施这个概念时遇到了问题。 有3个类需要持久化,

Class1,其中4个中的2个字段将存储在其他2个不同的表中

@Entity
@Table(name = "MAIN_CAT")
@SecondaryTables({

    @SecondaryTable(name = "CAT_1", pkJoinColumns = {
            @PrimaryKeyJoinColumn(name = "CAT1_PK", referencedColumnName = "id")
        }),
    @SecondaryTable(name = "CAT_2", uniqueConstraints = {
            @UniqueConstraint(columnNames = {"storyPart2"})
    })
})
public class Cat {

    @Id@GeneratedValue
    private Long id;

    private String catName;

    @Column(table = "CAT_1")
    private String storyPart1; // this field is going to be stored in CAT_1

    @Column(table = "CAT_2")
    private String storyPart2; // and so on
    // getters and setters
}

第2课:持久化时此类将存储上述持久化类的storyPart1字段

@Entity
@Table(name = "CAT_1")
public class CatOne {

    @Id
    @GeneratedValue
    @Column(name = "CAT1_PK")
    private Long CAT1_PK;

    @Column(name = "CATNAME_1")
    private String catName1;

    @Column(name = "CATAGE_1")
    private String catAge1;
    // getters and setters
}

第3课:持久化时此类将存储持久化Class 1的storyPart2字段

@Entity
@Table(name = "CAT_2")
public class CatTwo {

    @Id
    @GeneratedValue
    private Long id;

    @Column(name = "CATNAME_2")
    private String catName2;

    @Column(name = "CATAGE_2")
    private String catAge2;
    // getters and setters
}

数据库中创建的3个表是:

对于第1课:

CREATE TABLE main_cat
(
  id bigint NOT NULL,
  catname character varying(255),
  CONSTRAINT main_cat_pkey PRIMARY KEY (id)
)

第2课:

CREATE TABLE cat_1
(
  storypart1 character varying(255),
  cat1_pk bigint NOT NULL,
  catage_1 character varying(255),
  catname_1 character varying(255),
  CONSTRAINT cat_1_pkey PRIMARY KEY (cat1_pk),
  CONSTRAINT fk_kvtvo6nrv78wxkm0kv01k9kdq FOREIGN KEY (cat1_pk)
      REFERENCES main_cat (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)

对于第3课:

CREATE TABLE cat_2
(
  storypart2 character varying(255),
  id bigint NOT NULL,
  catage_2 character varying(255),
  catname_2 character varying(255),
  CONSTRAINT cat_2_pkey PRIMARY KEY (id),
  CONSTRAINT fk_2duj6ebg3504x18mlw2xkpvg6 FOREIGN KEY (id)
      REFERENCES main_cat (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT uk_5ko8732qslvvx98gy0q666qrf UNIQUE (storypart2)
)

问题是,它不是在CAT_1中插入记录,而是为同一个触发2个插入。将记录插入CAT_2也会发生同样的事情。

         Cat cat = new Cat();

         cat.setCatName("CAT Name");
         cat.setStoryPart1("STORYPART1");
         cat.setStoryPart2("STORYPART2");

         CatOne catOne = new CatOne();

         catOne.setCatAge1("10");
         catOne.setCatName1("catName1");

         CatTwo catTwo = new CatTwo();

         catTwo.setCatAge2("12");
         catTwo.setCatName2("catName2");

         session.save(cat);
         session.save(catOne);
         session.save(catTwo);

说明:

Hibernate: insert into CAT_1 (storyPart1, CAT1_PK) values (?, ?)
Hibernate: insert into CAT_1 (CATAGE_1, CATNAME_1, CAT1_PK) values (?, ?, ?)

由于将单个insert语句拆分为2语句,Hibernate会抛出此错误。

Caused by: org.postgresql.util.PSQLException: ERROR: insert or update 
on table "cat_1" violates foreign key constraint 
"fk_kvtvo6nrv78wxkm0kv01k9kdq" Detail: Key (cat1_pk)=(2) is not 
present in table "main_cat".

看起来我以错误的方式实现了@SecondaryTable概念。在这种情况下如何使Hibernate触发单个插入?

1 个答案:

答案 0 :(得分:2)

如果您已经将某个表用作实体的辅助表,那么将该表映射到另一个实体也不是一个好主意。辅助表应该被理解为给定实体的另一个表,它只能通过该实体进行管理。

如果您在辅助表上已有实体,则使用常规实体映射@OneToOne@ManyToOne等。