@Entity 无法识别 @MappedSuperclass 中的 @Id

Posted

技术标签:

【中文标题】@Entity 无法识别 @MappedSuperclass 中的 @Id【英文标题】:@Entity not recognizing the @Id in a @MappedSuperclass 【发布时间】:2012-08-21 13:01:36 【问题描述】:

我正在尝试为一组实体创建一个基类,以减少编码工作和重复。我的想法是基类具有公共元数据字段,子类处理它们的独特属性。

我的基类:

@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 

我已经使用此代码编写了测试来对 Tag 实体执行 CRUD 功能,它们都工作正常。

我的问题是 - 为什么 Eclipse (Indigo) 坚持认为 Tag 有错误:

The entity has no primary key attribute defined

我现在已将其更改为警告,以便我的代码能够编译,但我很好奇 Eclipse 为什么不高兴,以及我是否误解了什么。

这是有效的 JPA 2.0 代码吗? Hibernate 4.1.5 是我的 JPA 提供程序。

【问题讨论】:

此警告/错误是错误的,您可以在首选项中禁用它 【参考方案1】:

使用混合访问时,您必须指定访问类型。请参阅 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;
    

【讨论】:

宾果游戏!事实证明,我在版本字段上使用了字段访问,尽管我在其余字段上使用了属性访问。一旦我为我的版本字段创建访问器并将我的 @Version 注释移动到 getter,错误就消失了!【参考方案2】:

如果FinanceEntityBean 是在与Tag 不同的Eclipse 项目中定义的,您可能遇到了Dali 错误"No primary key attribute in other plug-in project"。

解决方法是在与Tag 关联的persistence.xml 文件中列出FinanceEntityBean

【讨论】:

我的错误不同,而且我(感谢 Dali)在我的 persistence.xml 中已经有 FinanceEntityBean,所以解决方法在我的情况下不起作用,但我很欣赏对 Dali 错误的引用。 【参考方案3】:

我相当肯定这些是有效的映射。

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)  ... 

【讨论】:

【参考方案4】:

我有同样的问题,但出于不同的原因,但我没有意识到。在进一步的研究中,我发现在我的情况下,我将 MappedSuperclass 放在不同的 jar 中。据网友气https://***.com/users/3701228/gas:

“根据 JPA 规范,如果你在单独的 jar 中有 jpa 类,你应该将它添加到 persistence.xml(我不知道,如果 Hibernate 需要,但你可以尝试一下)。尝试添加进入您的 persistence.xml entity.jar"

他引用what is the right path to refer a jar file in jpa persistence.xml in a web app? 作为对如何执行此操作的描述。

【讨论】:

【参考方案5】:

我知道这已经晚了,但这仍然是一个问题。感谢@Kemoda 在对该问题的评论中指出,这可以在 Eclipse 首选项中关闭。

“纠正”此问题的最简单方法是设置您认为适合您的环境的首选项。我喜欢“警告”,因为在实体没有主键的情况下是错误情况。

JPA 错误/警告 类型 实体没有主键:[Error|Warning|Info|Ignore]

【讨论】:

以上是关于@Entity 无法识别 @MappedSuperclass 中的 @Id的主要内容,如果未能解决你的问题,请参考以下文章

Nuget PM 中无法识别 Entity Framework Core 命令

system.data.Entity 给出错误?

实体识别+entity resolution

LINQ to Entity 减去 2 个日期

spring boot + JPA + MySql + Entity 表生成大写

C#学习教程:LINQ to Entities无法识别方法’System.String Split(Char )’方法