为什么我要用JPA共享ID?

时间:2016-03-10 21:18:19

标签: java jpa eclipselink

我有一个关于JPA和继承(EclipseLink)的问题:

对于学校项目,我创建了一个抽象类:HumanEntity 以及实现它的不同子类。

抽象类:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class HumanEntity implements IHuman{

@Id
@GeneratedValue
protected long      id;

@Column(name = "FIRST_NAME")
protected String    firstName;

@Column(name = "LAST_NAME")
protected String    lastName;

protected LocalDate birthDate;

protected HumanEntity(){

}

@Override
public String getFirstName() {
    return firstName;
}

@Override
public String getLastName() {
    return lastName;
}

@Override
public LocalDate getBirthDate() {
    return birthDate;
}

}

子类示例:

@Entity
@Table(name="ACTOR")
public class ActorEntity extends HumanEntity{

protected ActorEntity(){}

protected ActorEntity(ActorBuilder actorBuilder){
    this.firstName  = actorBuilder.getFirstName();
    this.lastName = actorBuilder.getLastName();
    this.birthDate  = actorBuilder.getBirthDate();
}

}

当我运行项目时: - > Ids是为每个子类共享的,然后我有

在演员表中: 1 - > .... 3 - > ....

在导演表中: 2 - > ....

如何为每个子类创建不同的Id,但在我的代码中使用受保护(共享)ID?

另一个小问题EclipseLink或JPA总是创建一个序列表,但我不知道它用于什么?我可以删除吗?

非常感谢!

2 个答案:

答案 0 :(得分:1)

类型为HumanEntity或子类的所有对象都是HumanEntity的实例,因此id需要保持一致,因此需要来自相同的“组”ID。

对于Actor的{​​{1}} ID 1,您不能说id为1,因为它们都是Director,您需要唯一标识HumanEntity。演员#1也是HumanEntity#1。因此,你也不能拥有导演#1,因为那也是HumanEntity#1!

如果你想拥有像那样的id那么你需要改变你的继承结构。

答案 1 :(得分:0)

首先,您使用的是哪个数据库平台会很有趣。正如你提到的学校项目,我认为它是PostgreSQL还是MySQL?!

ID的值基于与@GeneratedValue注释一起使用的策略(请参阅GenerationType)。如果您没有为@GeneratedValue - 字段指定任何具体策略,则根据JPA JavaDoc of GeneratedValue,默认策略应为javax.persistence.GenerationType.AUTO。但是,EclipseLink似乎根据documentation使用javax.persistence.GenerationType.TABLE

  

GenerationType:
  GeneratedValue的策略由GenerationType枚举类型定义。该策略定义了如何在数据库上生成id值。默认情况下,EclipseLink使用名为SEQUENCE的表选择TABLE策略,其中包含SEQ_NAME和SEQ_COUNT列,其allocationSize为50,pkColumnValue为SEQ_GEN。如果使用SEQUENCE,则使用的默认数据库序列名为SEQ_GEN_SEQUENCE,其allocationSize为50.

这基本上意味着EclipseLink将使用非业务数据库表SEQUENCE来查找下一个值。此外,它将使用此表的SEQ_GEN行生成所有默认生成的值。也就是说,默认情况下,所有实体都将共享生成值的公共池。我现在手头没有DMBS,但是查看此表可能会让您对使用的值有更多的了解。

如果您想使用其他策略或其他表进行生成,您应该查看TableGeneratorSequenceGenerator的JavaDoc。这样你就可以为每个子类创建一个单独的序列。

我认为上面已经回答了关于序列表的问题(至少我希望如此)。所以我不想删除它.​​.....