Overriding @Id defined in @MappedSuperclass with JPA

I have an AbstractEntity class that is extended by all entities in my application and basically acts as an identity provider.

@MappedSuperclass
public class AbstractEntity implements DomainEntity {

    private static final long serialVersionUID = 1L;

    /** This object id */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected long id;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="creation_date", nullable = false, updatable=false)
    private Date creationDate = new Date();

    /**
     * @return the id
     */
    public long getId() {
        return this.id;
    }

    /**
     * @param id the id to set
     */
    public void setId(long id) {
        this.id = id;
    }
}

      

I have a case where I need to define a separate Id for a couple of my Entity classes as they need to have their own sequence generator. How can this be achieved?

@Entity
@Table(name = "sample_entity")
public class ChildEntity extends AbstractChangeableEntity {

    @Column(name = "batch_priority")
    private int priority;

    public int getPriority() {
        return priority;
    }

    public void setPriority(int priority) {
        this.priority = priority;
    }

}

      

+6


source to share


3 answers


You cannot do this. Check out this GitHub example if you like.

Once defined @Id

in a base class, you cannot override it in a subclass, which means that it is better to leave the responsibility @Id

for each specific class.



Check out this article for more details.

+5


source


Split the base class.

Defines all common fields, but ID:

@MappedSuperclass
public  abstract class AbstractEntityNoId implements DomainEntity {
 private static final long serialVersionUID = 1L;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="creation_date", nullable = false, updatable=false)
    private Date creationDate = new Date();
}

      

Continues above with default id generator:



@MappedSuperclass
public abstract class AbstractEntity extends AbstractEntityNoId {

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

    public Long getId(){
       return id;
    }
}

      

Classes that require the creation of custom IDs extend the first and second.

In this case, the existing code above should not be changed, except for objects that require the generation of custom identifiers.

+1


source


One solution that is not feasible in some cases is to use annotations for getters instead of fields. This will give you more flexibility, especially to override whatever you want.

In code:

@MappedSuperclass
public class AbstractEntity implements DomainEntity {

    private static final long serialVersionUID = 1L;

    protected long id;

    private Date creationDate = new Date();

    /**
     * @return the id
     */
    /** This object id */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getId() {
        return this.id;
    }

    /**
     * @param id the id to set
     */
    public void setId(long id) {
        this.id = id;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="creation_date", nullable = false, updatable=false)
    public Date getCreationDate () {
        return this.creationDate ;
    }
}

      

And your subclass:

@Entity
@Table(name = "sample_entity")
public class ChildEntity extends AbstractChangeableEntity {


private int priority;

@Override
@Id
@GeneratedValue(strategy = GenerationType.ANOTHER_STRATEGY)
public long getId() {
    return this.id;
}

@Column(name = "batch_priority")
public int getPriority() {
        return priority;
    }
public void setPriority(int priority) {
        this.priority = priority;
    }

      

}

+1


source







All Articles