Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate: Overriding Field Optionality in Subclass

Is there a way, using Hibernate or JPA annotations, to override the optionality of a field in a subclass? Take the following example:

Parent Class

This is a base class that defines a number of common fields. For the example below, I am just showing a single field that I want to override in a few sub classes. In the @MappedSuperclass, this field is required (doesn't allow null).

@MappedSuperclass
public abstract class GenericLog {
  protected String sessionId;

  @Basic(optional = false)
  @Column(name = FIELD__SESSION_ID__COLUMN, length = 50)
  public String getSessionId() {
    return sessionId;
  }

  public void setSessionId(String sessionId) {
    this.sessionId = sessionId;
  }
}

Child Class

This is a subclass. It has the same sessionId field defined in the parent class, the only difference is that the field should allow nulls in this class.

@Entity
@Table(name = LogError.TABLE_NAME)
@Cache(usage = CacheConcurrencyStrategy.NONE)
public class LogError extends GenericLog {
  @Basic(optional = true)
  @Column(name = FIELD__SESSION_ID__COLUMN, length = 50)
  @Override
  public String getSessionId() {
    return super.getSessionId();
  }

  @Override
  public void setSessionId(String sessionId) {
    super.setSessionId(sessionId);
  }
}

I tried using the @AttributeOverride annotation, but that didn't work, even specifying the nullable property.

P.S. I'm using Hibernate 4.1.9 (JPA 2.0 annotations).

like image 701
Steven Benitez Avatar asked Sep 01 '25 03:09

Steven Benitez


1 Answers

I think there's some non-documented interaction between @Basic and @Column that prevent the effect of @AttributeOverride.

Remove the @Basic and move the annotation to the field level instead of method level did the trick for me:

Here is my setup:

@MappedSuperclass
public abstract class GenericLog {

  @Column(name = "sessionId", length = 50, nullable = false)
  protected String sessionId;

  // getter setter here
}

@Entity
@Table(name = "child")
@AttributeOverride(column = @Column(name = "sessionId", length = 50, nullable = true), name = "sessionId")
public class ChildEntity extends SuperClass {

    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    // getter setter here
}

@Entity
@Table(name = "child2")
public class ChildEntity2 extends SuperClass {

    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    // Getter setter here
}

Here's the result:

Table <code>child</code> Table <code>child2</code>

like image 129
Mạnh Quyết Nguyễn Avatar answered Sep 02 '25 17:09

Mạnh Quyết Nguyễn