【问题标题】:Eclipselink ValidationExceptionEclipselink 验证异常
【发布时间】:2011-07-25 18:54:29
【问题描述】:

我正在尝试调整我的数据模型以使用 BaseEntity 基类。下面的代码代表了大致的思路:

    @MappedSuperclass
    public abstract class BaseEntity implements HasAuditInfo {
        @Id
        @GeneratedValue
        private Long id;
        @Column(unique = true, nullable = false)
        private String uuid;
        private Long createdById;
        @Temporal(value = TemporalType.TIMESTAMP)
        @Column(nullable = false)
        private Date createdOn;
        private Long changedById;
        @Temporal(value = TemporalType.TIMESTAMP)
        @Column(nullable = false)
        private Date changedOn;
        @Column(nullable = false)
        private Long changedOnValue;
        private Boolean active;
        private Long deactivatedById;
        @Temporal(value = TemporalType.TIMESTAMP)
        private Date deactivatedOn;
        @NotNull
        @DecimalMin("0")
        private Integer version = 0;
        private Long domainId;

        [... Getters/Setters etc ...]
}

以下是派生实体的示例:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Address extends BaseEntity implements Serializable, Comparable<Address> {
    private static final long serialVersionUID = 6301090657382674578L;
    // Address Fields
    @NotBlank(message = "Address Line 1 is a mandatory field.")
    private String addressLine1;
    private String addressLine2;
    private String country;
    @NotBlank(message = "Region is a mandatory field.")
    private String region;
    @NotBlank(message = "City is a mandatory field.")
    private String city;
    @NotBlank(message = "Zipcode is a mandatory field.")
    private String zipcode;

    [... Getters/Setters etc ...]
}

如果我正确理解了 JPA 文档,这应该是完全有效的,但是在部署我的代码时我从 EclipseLink 收到以下错误:

实体类 [class com.x.y.z.Address] 没有指定主键。 它应该定义@Id、@EmbeddedId 或@IdClass。如果你 已使用这些注释中的任何一个定义了 PK,然后确保您 没有混合访问类型(字段和属性都已注释) 在您的实体类层次结构中。

我已经尝试了一些方法来解决这个问题:

  • 升级到 EclipseLink 2.3(我目前使用的是 2.2)
  • 使 BaseEntity 非抽象
  • 将@Id 注释和字段直接移动到地址中
  • 在 BaseEntity 和 Address 中注释 getId() 方法而不是字段。

除了将我的代码迁移到 Hibernate(或其他更好的 JPA 实现)之外,这些方法都没有任何效果,我能做些什么吗?

【问题讨论】:

  • BaseEntityTestAuditInfo 有什么关系?
  • TestAuditInfo 应该是 BaseEntity,已修复。

标签: java inheritance jpa eclipselink


【解决方案1】:

解决方法是在BaseEntity中显式命名每一列,如下:

@MappedSuperclass
public abstract class BaseEntity {
       @Id
       @GeneratedValue
       @Column(name = "id")
       @SearchableId
       protected Long id;
       @Column(name = "uuid", unique = true, nullable = false)
       protected String uuid;
       @Column(name = "createdById")
       protected Long createdById;
       @Temporal(value = TemporalType.TIMESTAMP)
       @Column(name = "createdOn", nullable = false)
       protected Date createdOn;
       @Column(name = "changedById")
       protected Long changedById;
       @Temporal(value = TemporalType.TIMESTAMP)
       @Column(name = "changedOn", nullable = false)
       protected Date changedOn;
       @Column(name = "changedOnValue", nullable = false)
       protected Long changedOnValue;
       @Column(name = "active")
       protected Boolean active;
       @Column(name = "deactivatedById")
       protected Long deactivatedById;
       @Temporal(value = TemporalType.TIMESTAMP)
       @Column(name = "deactivatedOn")
       protected Date deactivatedOn;
       @Version
       @Column(name = "version")
       protected Integer version = 0;
       @Column(name = "domainId")
       protected Long domainId;

【讨论】:

    【解决方案2】:

    您不应该收到此错误。如果您将@Id 移到地址中,则绝对不会。

    您确定在进行更改后重新编译/部署了您的代码吗?

    如果您删除 TABLE_PER_CLASS 继承,它会起作用吗? (Address 有子类吗?)

    【讨论】:

    • 是的,我已经尝试了这两个建议。我实际上已经找到了解决方案,但在这里忘记了我的问题!我会尽快发布解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多