简体   繁体   中英

JPA, Hibernate: fields of subclasses are null with @MappedSuperclass and InheritanceType.JOINED strategy

I'm trying to persist a Person entity, but I keep getting this null constraint violation error:

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

What I have tried:

  • With and without the Discriminator annotations
  • Setting the value in @PrePersist
  • Initializing createdById in the base class with a default value
  • Making the Party class instantiable (not abstract), and persisting it directly - THAT WORKS, but it's not what I need

For some reason, the createdById is null by the time the SQL gets generated and passed off to to PostgreSQL. (I have verified in debug mode that this field is set, on the person entity, when it gets passed to the DAO save call.)

I'm using Spring boot, Hibernate, and PostgreSQL to map my tables and classes like this:

@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 );
    }
}

The Party class, although abstract, maps to a PARTY table:

@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 ... */
}

The PartyType enum is registered with an AttributeConverter , with @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 */
}

Are you sure that the entity listener method is called? Are you sure that there is no other method that might set the value to null?

If all that doesn't help, please create a reproducing test case and submit an issue to the Hibernate issue tracker .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM