【问题标题】:JPA, Hibernate: fields of subclasses are null with @MappedSuperclass and InheritanceType.JOINED strategyJPA,Hibernate:子类的字段为空,@MappedSuperclass 和 InheritanceType.JOINED 策略
【发布时间】:2021-02-23 11:02:54
【问题描述】:

我正在尝试保留 Person 实体,但我不断收到此空约束违规错误:

org.postgresql.util.PSQLException: ERROR: null value in column "created_by_party_id" violates not-null constraint
  Detail: Failing row contains (5023, John, null, Smith, null, 1, null, null, 2020-11-11 07:33:31.590766-05, null, null, null).

我尝试过的:

  • 有和没有鉴别器注释
  • 设置@PrePersist中的值
  • 使用默认值在基类中初始化createdById
  • 使 Party 类可实例化(不是抽象的),并直接将其持久化 - 可行,但这不是我需要的

由于某种原因,在生成 SQL 并将其传递给 PostgreSQL 时,createdById 为空。 (我已经在调试模式下验证了在 person 实体上设置了该字段,当它被传递到 DAO 保存调用时。)

我正在使用 Spring boot、Hibernate 和 PostgreSQL 来映射我的表和类,如下所示:

@MappedSuperclass
@EntityListeners( value = { EntityAuditListener.class } )
public abstract class BaseJPA {

    @Column(name = "created_by_party_id", nullable = false)
    private Long createdById = 1l;

    /* Getters and Setters ... */
}
public class EntityAuditListener {
    @PrePersist
    public void prePersist(BaseJPA jpa) {
        jpa.setCreatedById( 1l );
    }
}

Party 类虽然是抽象的,但映射到一个 PARTY 表:

@Entity(name = "Party")
@Table(name = "PARTY")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "PARTY_TYPE_CODE", discriminatorType = DiscriminatorType.INTEGER)
public abstract class Party extends BaseJPA implements Serializable {

    private static final long serialVersionUID = 5434024967600745049L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "PARTY_ID_SEQ")
    @SequenceGenerator(name = "PARTY_ID_SEQ", sequenceName = "PARTY_ID_SEQ", allocationSize = 1)
    @Column(name = "PARTY_ID")
    protected Long partyId;

    @Column(name = "PARTY_TYPE_CODE", insertable = false, updatable = false)
    protected PartyType partyType;

    /* Getters & Setters ... */
}

PartyType 枚举使用 AttributeConverter 注册,@Converter(autoApply = true)

public enum PartyType {
    PERSON(1), UNIT(2), SYSTEM(3);

    private final int value;

    PartyType(int value) {
        this.value = value;
    }
    /* Getter */
}
@Entity(name = "Person")
@Table(name = "PERSON")
@DiscriminatorValue( "1" )
@Inheritance(strategy = InheritanceType.JOINED)
public class Person extends Party implements Serializable {

    private static final long serialVersionUID = -5747077306637558893L;

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

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

    /* More fields ...*/

    public Person() {
        this.partyType = PartyType.PERSON;
    }

    /* Getters & Setters */
}

【问题讨论】:

    标签: java postgresql spring-boot hibernate jpa


    【解决方案1】:

    您确定调用了实体侦听器方法吗?您确定没有其他方法可以将该值设置为 null 吗?

    如果所有这些都没有帮助,请创建一个复制的test case 并将问题提交给Hibernate issue tracker

    【讨论】:

    • 前两个问题是的...我应该提到我的数据库模式不是由 Hibernate 创建的,而是预先生成的。当我尝试使用上面的代码在 PostgreSQL 中保留 Person 时,我得到了 person 实体上的 created_by_party_id 字段的空约束违规。
    • 但是当我尝试持久化 Hibernate 生成的表时(在 PostgreSQL 或 H2 中,使用 Hibernate 测试用例),PERSON 表没有创建 created_by_party_id 列,这是我正在寻找的。如果这是一个错误,我很乐意将代码发布到问题跟踪器。否则我期待并试图弄清楚如何从BaseJPA 中获取createdById 字段以包含在从它扩展的任何级别的类中。
    • 你能发布完整的 BaseJPA 类以及 persistence.xml 吗?
    • 我发布了测试用例here。测试用例中没有修改persistence.xml,在我的真实项目中我使用的是Spring boot(默认设置,没有修改)。
    • 更新:我刚刚在 Hibernate 4 中尝试过,得到了相同的结果 :-(。我的映射是否遗漏了什么?
    猜你喜欢
    • 2012-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    • 2021-11-20
    • 1970-01-01
    相关资源
    最近更新 更多