How can i map inheritance class in Hibernate :
For example i have abstract class figure and two child classes Square and Circle. How can i map them all to be in one table, for example "figures" ?
I have tried something like this
#Entity
#Table(name = "figures")
public abstract Figure{
}
#Entity
#Table(name = "figures")
public class Square extends Figure{
}
#Entity
#Table(name = "figures")
public class Circle extends Figure{
}
but it doesnt work.
Thanks for any help :)
What you need to do is add annotations to parent class :
#Entity
#Inheritance(strategy=InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name="type", discriminatorType=DiscriminatorType.STRING)
#Table(name = "figures")
DiscriminatorColumn will be a new column created by hibernate to know what type this object is.
In my case I create a column with name "type"
And also annotations to all your child class
In DiscriminatorValue you need to insert a value that hibernate use to identify that class
In my case it is String. (discriminatorType in DiscriminatorColumn annotations)
#Entity
#DiscriminatorValue(V)
so in your case it could look like that :
#Entity
#Inheritance(strategy=InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name="type", discriminatorType=DiscriminatorType.STRING)
#Table(name = "figures")
public class Figure{
}
#Entity
#DiscriminatorValue("S")
public class Square extends Figure{
}
#Entity
#DiscriminatorValue("C")
public class Circle extends Figure{
}
You can find more info here : http://www.javatpoint.com/hibernate-table-per-hierarchy-using-annotation-tutorial-example
Related
I have two tables A and B:
#Entity
public class A {
}
#Entity
public class B {
private final A a;
private String someBSpecificField;
}
Entity A is already Coded nicely and mapped to an existing table. My job is to create B and for some reason I prefer composition over inheritance between A and B. At the same time I want to have single table for A and B to avoid joins when reading. Can I do like this:
#Entity
#Table(name = "a")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "a_type_enum", discriminatorType =
DiscriminatorType.INTEGER)
#DiscriminatorValue("100")
public class A {
}
#Entity
#Table(name = "a")
#DiscriminatorValue("500")
public class B {
private final A a;
private String someBSpecificField;
}
If the type is a complex object then you need to annotate that type with #Embeddable and use it in your #Entity class.
if you want to override the attribute names for your #Embeddable class so they have different column names, you can do so with the #AttributeOverrides annotation.
I have the following class structure:
I would like to generate the following three tables with hibernate:
PlanItem: with all its attributes
Task: with all its attributes and its child attributes
Stage: with all its attributes
I tried to mix the inheritancetypes but it didn't work:
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
public abstract class PlanItem {...}
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Stage extends PlanItem {...}
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Task extends PlanItem {...}
#Entity
public class HumanTask extends Task {...}
#Entity
public class ProcessTask extends Task {...}
#Entity
public class CaseTask extends Task {...}
I already experimented with secondary tables and got more or less the desired result:
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class PlanItem {...}
#Entity
#SecondaryTable( name = "Stage" )
public class Stage extends PlanItem {...}
#Entity
#SecondaryTable( name = "Task" )
public class Task extends PlanItem {...}
#Entity
#SecondaryTable( name = "Task" )
public class HumanTask extends Task {...}
#Entity
#SecondaryTable( name = "Task" )
public class ProcessTask extends Task {...}
#Entity
#SecondaryTable( name = "Task" )
public class CaseTask extends Task {...}
But I was wondering if a more elegant and simple solution exists?
That's currently not possible, see the following issue for further information. I think that your "hack" with using secondary tables is currently the best you can get.
I have a superclass that is an #Entity, something like this one:
#Entity
#Table(name = "utente")
public class Utente implements Serializable{
...
}
The subclass has just a #Transient field besides:
#Entity
public class UtenteSub extends Utente{
#Transient
private String newField;
}
To make it work, I should add #DiscriminatorValue, #Inheritance and add a field on the table.
This is a lot of work to do, taking into account that all I need in the subclass is just a #Transient field (I need it to "check" the object Utente after its "submission" in a form).
Is there a better and easier way to extend the #Entity in my scenario?
Thank you.
You could try creating an abstract base class UtenteBase:
#MappedSuperClass
public abstract class UtenteBase implements Serializable
{
//all mapped columns go here
}
All your mapped columns which were in Utente before are now in this class.
You can then extend this class with your two above mentioned classes:
#Entity
#Table(name = "utente")
public class Utente extends UtenteBase
{
public Utente {}
}
#Entity
#Table(name = "utente")
public class UtenteSub extends UtenteBase
{
#Transient
private String newField;
}
The class Utente is the concrete implementation class and is used for the communication with the database.
Both classes are in the same inheritance tree and you don't need to add a DiscriminatorValue and change the table.
I have this strange hierarchy:
Class A is abstract (but it is an entity)
Class B (abstract) and C both extend class A (TABLE_PER_CLASS).
Class B is also extended by classes D and E but this time it is JOINED.
I want the ID of the A class to be the ID of all others.
Can this be done?
I get strange errors of IDs. can any one show me how to map?
This is how I did it:
#Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class A {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
protected Integer id;
}
Class C:
#Entity
#Table(name = "managers")
public class C extends A {
Class B:
#Entity
#Table(name = "bb")
#Inheritance(strategy = InheritanceType.JOINED)
#DiscriminatorColumn(name = "discriminator", discriminatorType = DiscriminatorType.STRING)
public abstract class B extends A {
Class C,D:
#Entity
#Table(name = "cc"/"dd")
#DiscriminatorValue("CC"/"DD")
public class C (or D) extends B {
While mixing inheritance strategies in an inheritance tree can be sort of accomplished (https://stackoverflow.com/a/3916998/131929 refers to Java Persistence with Hibernate
-> 5.1.5 Mixing inheritance strategies (p207-p210)) I, and everybody else I know, advise against it.
Sidenote, I suggest you always use #MappedSuperclass rather than #Entity for abstract classes.
We create our tables automaticly via Hibernate by assigning:
#Table(name = "some_table")
That used to work for "normal" entities. But when we have an abstract base class:
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class PersonBankAccount extends AbstractPersistable<Long> {
that is extended by
#Entity
#Table(name = "person_bank_account")
public class PersonBankAccountSimple extends PersonBankAccount {
The resulting table in the database is named
personbankaccount
What is going on here?
The autogenerator says:
table not found: PersonBankAccount
when first creating it and on rerun he says:
table found: personbankaccount
Like I said, for normal tables everything works fine.
Shouldn't be the name of table in the base class instead.
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#Table(name = "person_bank_account")
public class PersonBankAccount extends AbstractPersistable<Long> {