kmualem
kmualem

Reputation: 135

Hibernate Annotations - @MappedSuperclass How to override column identifier

I'm working with Hibernate Annotations and the issue that I'm trying to solve goes as follows:

I need to have 2 different @Entity classes with the same columns mapping but with a different Identifier.

The first one should use id as identifier.

The second should use name as identifier.

So, I have an abstract class, annotated with @MappedSuperclass that have all of the columns including id and name, and in addition 2 @Entity classes that extends the super class and overriding the getters of the id and name.

@MappedSuperclass 
public class MappingBase {
    protected Integer id;
    protected String name;

    @Column (name = "ID")
     public void getId() {
          return this.id;
     }

    @Column (name = "NAME")
     public void getName() {
          return this.name;
     }              
}

@Entity
@Table (name = "TABLE")
public class Entity1 extends MappingBase {

  @Id
  @Column (name = "ID")
  public void getId() {
    return this.id;
  } 
}

@Entity
@Table (name = "TABLE")
public class Entity2 extends MappingBase {

  @Id
  @Column (name = "NAME")
  public void getName() {
      return this.name;
  } 
}

Note: I must have the members (id,name) in the super class. I know that i can add @Transient to the id and name getters but this means that i must add both of them in each class and it's not a good design :( In addition, the following insertable="false, updateable=false can help but i don't understand what is the meaning of this...

Please help me!

Upvotes: 2

Views: 21587

Answers (3)

misbah
misbah

Reputation: 189

Hibernate/JPA allows us to annotate either properties or accessors. If we have @Id annotation on a property, JPA will lookup all the properties of the class. Similarly, if we have @id annotation on a getter method, JPA will lookup all the getters.

We can solve the above problem by annotating properties instead. The superclass and the two subclasses will be as follows-

@MappedSuperclass
public abstract class AbstractMappingBase {

    //properties other than id and name

    public abstract Integer getId();

    public abstract String getName();

    //other getters and setters

}

@Entity
public class Entity1 extends AbstractMappingBase {

    @Id
    private Integer id;

    private String name;

    @Override
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Override
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

@Entity
public class Entity2 extends AbstractMappingBase {

    private Integer id;

    @Id
    private String name;

    @Override
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Override
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Here JPA will look for properties instead of getters. There are no duplicate properties between superclass and its subclasses. So it will work fine.

Upvotes: 3

kmualem
kmualem

Reputation: 135

If i remember correctly, I simply defined 2 @Entity classes with the same table that inherits from one abstract @MappedSuperclass class. The super class contains the id member and each Entity class define it's own @Id @Column definition. It should work!

Upvotes: 0

dinukadev
dinukadev

Reputation: 2297

You are much better off defining your base class as @Embeddable and using @Embedded in your implementation classes with the use of @AttributeOverride.

Upvotes: 1

Related Questions