I have the following superclass that will be extended by many classes. Its one property, foreignKey, will be the #Id for one of the inheriting classes.
The superclass:
#MappedSuperclass
public abstract Superclass {
#Column(name="FOREIGN_KEY")
private String foreignKey;
// Getters and setters
}
The inheriting class:
#Entity
public class ClassA extends Superclass {
#Id
#Column(name="FOREIGN_KEY")
private String foreignKey;
// Getters and setters
}
When I try building I am given the error:
No identifier specified for ClassA
Is there anyway to accomplish this?
Related
I have a simple base class in which I want to have some common fields, like id etc. The base class is not an Entity by itself.
public class Base {
#Id
protected long id;
protected String someOtherCommonProperty;
}
And I have an entity class, extending the base class.
#Entity
public class Entity extends Base {
String name;
String address;
}
I would expect the entity class to inherit the fields from the base class, but what I get is
[ObjectBox] No #Id property found for 'Entity', add #Id on a not-null long property.
Is there any way to fix that, besides using interfaces and have a lot of duplicated code?
You can use the #BaseEntity annotation.
Have a look at the documentation: Objectbox - Entity Inheritence.
Shameless copy for future reference:
In addition to the #Entity annotation, we introduced a #BaseEntity annotation for base classes, which can be used instead of #Entity.
There three types of base classes, which are defined via annotations:
No annotation: The base class and its properties are not considered for persistence.
#BaseEntity: Properties are considered for persistence in sub classes, but the base class itself cannot be persisted.
#Entity: Properties are considered for persistence in sub classes, and the base class itself is a normally persisted entity.
Example:
// base class:
#BaseEntity
public abstract class Base {
#Id long id;
String baseString;
public Base() {
}
public Base(long id, String baseString) {
this.id = id;
this.baseString = baseString;
}
}
// sub class:
#Entity
public class Sub extends Base {
String subString;
public Sub() {
}
public Sub(long id, String baseString, String subString) {
super(id, baseString);
this.subString = subString;
}
}
How can I tell hibernate to ignore a field during schema auto generation?
In this special case: the field is inherited from a parent abstract class, so I cannot just comment it out!
I tried using #Transient, but the field is still autogenerated in the schema.
#MappedSuperclass
public abstract class BaseEntity {
private String someField;
//getter+setter
}
#Entity
public class MyEntity extends BaseEntity {
#Transient //I want to ignore this field during hibernate.ddl.auto
#Override
public String getSomeField() {}
}
Add the Transient annotation in the super class:
#MappedSuperclass
public abstract class BaseEntity {
#Transient
private String someField;
}
#Entity
public class MyEntity extends BaseEntity {
}
I have an interface called Rule with 2 implementing classes who all share one Abstract base class.
#MappedSuperclass
public interface Rule { .. }
#Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class BaseRule implements Rule {
#Entity
public class ImlementingRule1 extends BaseRule {
#Entity
public class ImlementingRule1 extends BaseRule {
I'm using this Rule interface in a containgRules class as such:
#OneToMany
#JoinColumn(name = "RULES_ID")
private List<Rule> rules;
Whatever setup I try I always end up with:
Caused by: org.hibernate.MappingException: Cannot use identity column key generation with <union-subclass> mapping for: mynamespace.BaseRule
I personally have found no other solution than to use the abstract base class, instead of interface.
#OneToMany
#JoinColumn(name = "RULES_ID")
private List<BaseRule> rules;
It states right here:
Annotating interfaces is currently not supported.
i have a generic class which is supper class of some non-generic class and those are just setting its generic parameter like this:
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
class A<T>{
#Id
getId(){..}
setID(int id){..}
int id
T t;
T getT(){...}
setT(T t){...}
}
and
#Entity
class B extends A<Integer>{}
but hibernate says that B does not have an identifier what should I do?
If A won't be directly persisted, but you do want it's subclasses to pick up some (or all) of its Hibernate annotations, you should use #MappedSuperclass:
#MappedSuperclass
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
class A<T>{
#Id
getId(){..}
setID(int id){..}
int id
T t;
T getT(){...}
setT(T t){...}
}
You need to add the #Entity annotation to class A as well.
The #Transient annotation on attribute t should help with your second exception
#Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
class A<T> {
#Id
getId(){..}
setID(int id){..}
int id
#Transient
T t;
T getT(){...}
setT(T t){...}
}
I agree with reply No. 1, use #MappedSuperclass for A - don't make something abstract an Entity.
You should probably make this class specifically abstract too.
#MappedSuperclass
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
abstract class A<T>{
#Id
getId(){..}
setID(int id){..}
int id
T t;
T getT(){...}
setT(T t){...}
}
A table-per-class strategy often requires this kind of abstract base.
Then the subclass specifies the table name, and additional fields.
#Entity
#Table(name="MY_INTEGERS")
class B extends A<Integer>{}
(Personally I would move this variable type into the subclass, but I don't know what you're trying to achieve).
After lots of testing, trying to get Java parameterisation working with an abstract parent (Single-table inheritance), and an abstract child table (one-table-per-class inheritance), I've given up.
It may be possible, but often you get problems where Hibernate tries to instantiate an abstract (parameterised) class as an entity. this is when you get the error "A has an unbound type and no explicit target entity."
It means Hibernate doesn't have a parameter value for a parameterised type.
I found that tests for the extending classes were fine, but tests around parent entities would break.
I would suggest rewriting it using the JPA inheritance, moving the parameterised stuff down into extending classes. That way you get the same polymorphism back from the database.
#MappedSuperclass
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "CLASS_TYPE", discriminatorType = DiscriminatorType.STRING)
public abstract class ClassA {
[...]
}
extension B:
#Entity
#DiscriminatorValue=("B")
public class ClassB extends ClassA {
#OneToOne
#JoinColumn(name = "mycolumn_id")
private Integer instance;
[...]
}
extension C:
#Entity
#DiscriminatorValue=("C")
public class ClassC extends ClassA {
#OneToOne
#JoinColumn(name = "mycolumn_id")
private String instance;
[...]
}
I'm trying to duplicate something you can do in .Net but not having much luck.
Is the following not possible in Java or am I just missing something? When I run it I get told there is no identifier specified for entity Group.
public abstract class RCEntity
{
#Id #GeneratedValue
private int id;
//getters & setters
}
#Entity
public class Group extends RCEntity {
}
Add the annotation #MappedSuperclass to your super class, i.e.
#MappedSuperclass
public abstract class RCEntity
{
#Id #GeneratedValue
private int id;
//getters & setters
}
From this section in the docs:
Any class in the hierarchy non annotated with #MappedSuperclass nor #Entity will be ignored.