@MappedSuperClass in Hibernate = AnnotationException: Unknown mappedBy
-
13-11-2019 - |
Question
Error: Caused by: org.hibernate.AnnotationException: Unknown mappedBy in: com.xxx.data.dao.classes.Categories.categoriesLang, referenced property unknown: com.xxx.data.dao.classes.superclasses.CategoriesLang.categories
My setup:
Hibernate 3.5.6
public interface CategoriesLangInt {
int id_categories = 0;
Categories categories = null;
String name = "";
String description = "";
int getId_categories();
void setId_categories(int id_categories);
Categories getCategories();
void setCategories(Categories categories);
String getName();
void setName(String name);
String getDescription();
void setDescription(String description);
}
@MappedSuperclass
public abstract class CategoriesLang implements CategoriesLangInt {
@Id
@Column(name = "id_categories")
private int id_categories = 0;
@OneToOne
@JoinColumn(name = "id_categories")
private Categories categories;
@Size(max = 50)
private String name = "";
@Size(max = 350)
private String description = "";
@Override
public int getId_categories() {
return id_categories;
}
@Override
public void setId_categories(int id_categories) {
this.id_categories = id_categories;
}
@Override
public Categories getCategories() {
return categories;
}
@Override
public void setCategories(Categories categories) {
this.categories = categories;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public String getDescription() {
return description;
}
@Override
public void setDescription(String description) {
this.description = description;
}
}
@Entity
@Table(name="categories")
public class Categories implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id_categories;
private boolean active;
@OneToOne(mappedBy="categories")
private CategoriesLangInt categoriesLangInt;
public Integer getId_categories() {
return id_categories;
}
public void setId_categories(Integer id_categories) {
this.id_categories = id_categories;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
public CategoriesLangInt getCategoriesLangInt() {
return categoriesLangInt;
}
public void setCategoriesLangInt(CategoriesLangInt categoriesLangInt) {
this.categoriesLangInt = categoriesLangInt;
}
}
UPDATE SOLVED IT!!!
After a long time doing research in the end I succeed. It works fine!
@Entity
@Table(name="categories")
public class Category implements Serializable {
private Integer id;
private boolean active;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
}
public interface CategoryInt{
int getCategory_id();
void setCategory_id(int category_id);
String getName();
void setName(String name);
String getDescription();
void setDescription(String description);
void setCategory(Category category);
Category getCategory();
}
@MappedSuperclass
public abstract class CategoryLang implements CategoryInt{
private int category_id;
private String name;
private String description;
private Category category;
@Override
@Id
public int getCategory_id() {
return category_id;
}
@Override
public void setCategory_id(int category_id) {
this.category_id = category_id;
}
@Override
@Size(max = 50)
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
@Size(max = 350)
public String getDescription() {
return description;
}
@Override
public void setDescription(String description) {
this.description = description;
}
@Override
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
public Category getCategory() {
return category;
}
@Override
public void setCategory(Category category) {
this.category = category;
}
}
@Entity
@Table(name = "en_categories")
public class CategoryEN extends CategoryLang implements Serializable {}
@Entity
@Table(name = "es_categories")
public class CategoryES extends CategoryLang implements Serializable {}
Solution
First of all, an interface may not define fields, but only methods. The fields you have declared in the interface are in fact public static final constants.
After, the Categories entity has a CategoriesLangInt field, but Hibernate has no way to know which entity this field represents, since there might be several entities implementing this interface. You must use the targetEntity
attribute of the OneToOne annotation to tell Hibernate which entity is referenced.
Finally, the id_categories
column in CategoriesLang is mapped twice: once as an ID, and once as a JoinColumn. You must either remove the id_categories
field and annotate the categories
field with @Id, or leave id_categories
field as it is and add the @MapsId annotation to categories
.
Side note: you should respect the Java naming conventions (no underscore in fields and methods), and rename Categories to Category, CategoriesLang to CategoryLang, etc.
OTHER TIPS
I think it's because your fields in your superclass (interface, here) are shadowed by similarly named fields in the extending class. Try removing those fields from the interface (like categories).