我正在尝试为一组实体创建一个基类,以减少编码工作和重复。我的想法是,基类具有公共元数据字段,子类处理其独特的属性。
我的基班:
@MappedSuperclass
public abstract class FinanceEntityBean {
protected Long id;
@Version
private long version;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
}
第一个实体:
@Entity
@Table(name = "tag")
public class Tag extends FinanceEntityBean {
}
我已经使用此代码编写了测试,以在标签实体上执行 CRUD 功能,并且它们都工作正常。
我的问题是 - 为什么 Eclipse (Indigo) 坚持认为
Tag
有错误:
The entity has no primary key attribute defined
我现在已将其更改为警告,以便我的代码可以编译,但我很好奇为什么 Eclipse 不高兴,以及我是否误解了某些内容。
这是有效的 JPA 2.0 代码吗? Hibernate 4.1.5 是我的 JPA 提供程序。
使用混合访问时,您必须指定访问类型。请参阅 Eclipse Dali bug 323527,以在注释字段和属性时提供更好的验证错误。
选项 1 :改为注释 getVersion() 方法,仅注释属性。
选项 2:指定混合访问类型如下:
@MappedSuperclass
@Access(AccessType.PROPERTY)
public abstract class FinanceEntityBean {
protected Long id;
@Version
@Access(AccessType.FIELD)
private long version;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
}
如果
FinanceEntityBean
与 Tag
定义在不同的 Eclipse 项目中,您可能会遇到 Dali bug “其他插件项目中没有主键属性”。
解决方法是在与
FinanceEntityBean
关联的 persistence.xml
文件中列出 Tag
。
我相当确定这些是有效的映射。
JPA 2.0 规范在讨论 MappedSuperClasses 时提供了这个示例(第 2.11.2 节):
@MappedSuperclass
public class Employee {
@Id protected Integer empId;
@Version protected Integer version;
@ManyToOne @JoinColumn(name="ADDR") protected Address address;
public Integer getEmpId() { ... }
public void setEmpId(Integer id) { ... }
public Address getAddress() { ... }
public void setAddress(Address addr) { ... }
}
// Default table is FTEMPLOYEE table
@Entity public class FTEmployee extends Employee {
// Inherited empId field mapped to FTEMPLOYEE.EMPID
// Inherited version field mapped to FTEMPLOYEE.VERSION
// Inherited address field mapped to FTEMPLOYEE.ADDR fk
// Defaults to FTEMPLOYEE.SALARY protected Integer salary;
public FTEmployee() {}
public Integer getSalary() { ... }
public void setSalary(Integer salary) { ... }
}
我有同样的问题,但出于不同的原因,但我没有意识到。在进一步的研究中,我发现在我的例子中,我将 MappedSuperclass 放在另一个罐子中。根据用户 Gas https://stackoverflow.com/users/3701228/gas:
“根据 JPA 规范,如果您在单独的 jar 中有 jpa 类,您应该将其添加到 persistence.xml 中(我不知道,Hibernate 是否需要这样做,但您可以尝试一下)。尝试添加以下条目到你的 persistence.xml 实体.jar”
他引用了 在 Web 应用程序中引用 jpa persistence.xml 中的 jar 文件的正确路径是什么? 作为如何执行此操作的描述。
我知道这已经晚了,但这仍然是一个问题。谢谢 @Kemoda 在对该问题的评论中指出,这可以在 Eclipse 首选项中关闭。
“纠正”此问题的最简单方法是设置您认为适合您的环境的首选项。我喜欢“警告”,因为在实体没有主键的情况下是一种错误情况。
JPA 错误/警告 类型 实体没有主键:[错误|警告|信息|忽略]
对于面临此问题的其他人,请确保您导入的 @Id 来自 jakarta.persistence 而不是来自 org.springframework.data.annotation 包。
这发生在我身上,并且不得不花费大量时间试图找出真正的问题是什么。