Reputation: 135
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
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
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
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