Java 子类上的重复生成器序列休眠
我遵循此帖子来解决我最初的问题: 但现在我有一个例外: 调用init方法失败;嵌套异常是 java.lang.IllegalArgumentException:重复的生成器名称idgen 在我的类、子类和pom.xml下面: EntityId(抽象类)Java 子类上的重复生成器序列休眠,java,hibernate,jpa,Java,Hibernate,Jpa,我遵循此帖子来解决我最初的问题: 但现在我有一个例外: 调用init方法失败;嵌套异常是 java.lang.IllegalArgumentException:重复的生成器名称idgen 在我的类、子类和pom.xml下面: EntityId(抽象类) @MappedSuperclass 公共抽象类EntityId实现了可序列化{ 私有静态最终长serialVersionUID=1974679434867091670L; @身份证 @GeneratedValue(generator=“idge
@MappedSuperclass
公共抽象类EntityId实现了可序列化{
私有静态最终长serialVersionUID=1974679434867091670L;
@身份证
@GeneratedValue(generator=“idgen”,strategy=GenerationType.SEQUENCE)
@列(name=“id”)
受保护的T-id;
公共T getId(){
返回id;
}
公共无效设置id(T id){
this.id=id;
}
}
类别类别
@MappedSuperclass
public abstract class EntityId<T extends Serializable> implements Serializable {
private static final long serialVersionUID = 1974679434867091670L;
@Id
@GeneratedValue(generator="idgen", strategy=GenerationType.SEQUENCE)
@Column(name="id")
protected T id;
public T getId() {
return id;
}
public void setId(T id) {
this.id = id;
}
}
@Entity
@SequenceGenerator(name="idgen", sequenceName="cat_id_seq", allocationSize=1)
@AttributeOverrides({
@AttributeOverride(name="id", column = @Column(name="cat_id"))
})
@Table(name="categoria")
public class Category extends EntityId<Integer> {
private static final long serialVersionUID = -870288485902136248L;
@Column(name="name")
private String name;
@Column(name="description")
private String description;
}
@实体
@SequenceGenerator(name=“idgen”,sequenceName=“cat\u id\u seq”,allocationSize=1)
@属性溢出({
@属性覆盖(name=“id”,column=@column(name=“cat\u id”))
})
@表(name=“categoria”)
公共类类别扩展了EntityId{
私有静态最终长serialVersionUID=-870288485902136248L;
@列(name=“name”)
私有字符串名称;
@列(name=“description”)
私有字符串描述;
}
pom.xml
...
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.15.Final</version>
</dependency>
...
。。。
org.hibernate
从您提供的链接。JPA规范规定:
序列生成器可以在实体类或
主键字段或属性。生成器名称的作用域为
全局到持久性单元(跨所有生成器类型)
因此,让两个标识符生成器具有相同的名称和不同的配置是不合法的。范围是全局的,而不是实体
要解决您的问题,您应该将@Id从@MappedSuperclass推送到子类中
编辑、添加了可能的解决方法:
- 删除超类中字段的注释李>
- 使getter抽象化李>
- 让所有子类都有自己的序列生成器:所有生成器都应该有全局唯一名称李>
- 实施吸气剂李>
- 在getter上移动与Id字段相关的注释李>
公共接口EntityId扩展了可序列化{
公共T getId();
公共无效设置id(T id);
}
@实体
@表(name=“categoria”)
公共类类别实现EntityId{
私有静态最终长serialVersionUID=-870288485902136248L;
@身份证
@列(name=“cat_id”)
@SequenceGenerator(name=“cat\u id\u gen”,sequenceName=“categoria\u cat\u id\u seq”,allocationSize=1)
@GeneratedValue(generator=“cat\u id\u gen”,strategy=GenerationType.SEQUENCE)
私有整数id;
//其他属性在这里。。。
@凌驾
公共无效集合id(整数id){
this.id=id;
}
@凌驾
公共整数getId(){
返回此.id;
}
}
您的问题有答案可以在实体类或主键字段或属性上指定序列生成器。生成器名称的范围是持久性单元的全局范围(跨所有生成器类型)。
更多详细信息,请参阅[链接]下的注释(可以在实体类或主键字段或属性上指定序列生成器)。生成器名称的范围是持久性单元的全局范围().好的,但他没有解释“将\@Id从\@MappedSuperClass推到子类中”,这是Stefan Mueller提出的问题:“嗨,Vlad,推\@Id是什么意思?”。在我的子类中复制属性Id毫无意义。JPA规范也说:“字符串名称(必需)一个或多个类可以引用的唯一生成器名称,作为主键值的生成器。”首先,关于下推,它意味着将字段移动到子类。一些IDE可以帮助您自动执行此操作,例如Intellij IDEA。其次,您希望在所有子类中使用相同的字段。但您希望其中某些子类具有不同的行为。这是下推的一个好迹象。答案中添加了一个可能的解决方法。感谢您的帮助!我将尝试另一个w是的。我会尽快把我的反馈贴在这里。
public interface EntityId<T extends Serializable> extends Serializable {
public T getId();
public void setId(T id);
}
@Entity
@Table(name="categoria")
public class Category implements EntityId<Integer> {
private static final long serialVersionUID = -870288485902136248L;
@Id
@Column(name="cat_id")
@SequenceGenerator(name="cat_id_gen", sequenceName="categoria_cat_id_seq", allocationSize=1)
@GeneratedValue(generator="cat_id_gen", strategy=GenerationType.SEQUENCE)
private Integer id;
//others attributes here...
@Override
public void setId(Integer id) {
this.id = id;
}
@Override
public Integer getId() {
return this.id;
}
}