Java SingleTable inheritance in db structure using JPA/Hibernate - java

I have models/Entities as follow:
#Entity
#DiscriminatorColumn(name="type")
#Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public class Insurance extends Generic<Insurance> {
#OneToOne public myInsurance.models.liability.hivAndVHProtection.Hiv_Answer hivAndVHProtectionAnswer;
}
#MappedSuperclass
#Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class Answer extends Generic<Answer> {}
#Entity
#Inheritance(strategy=InheritanceType.SINGLE_TABLE)
#DiscriminatorValue("A")
public class Hiv_Answer extends Answer {
#OneToOne public HivAndVHProtection_Variant variant;
}
#Entity
#Inheritance
#DiscriminatorValue("E")
public class Hiv_AnswerForEntities extends Hiv_Answer {
public int proffesionGroup;
public int personCount;
public int contributionPerPerson;
#Transient public int totalContribution;
}
I would like to have in db two tables:
Insurance and Hiv_Answer
I would like that Entities: Hiv_Answer and Hiv_AnswerForEntities be persisted in table Hiv_Answer (share common ID pool)
I would like to have in table Insurance relation to table Hiv_Answer f.e. in column Hiv_Answer_id
I've tried a lot of combination with annotation. None worked like it supose.
Current configuration for me seems to be OK, but it isn't. I am getting extra table: Hiv_AnswerForEntities, and I don't have relation to Hiv_Answer table at all.
It seems that instead use strategy=InheritanceType.SINGLE_TABLE from Hiv_Answer Entity it use strategy=InheritanceType.TABLE_PER_CLASS from superclass Answer
I can't find my mistake.
Please help me solve this.

In JPA you can't redefine your inheritance strategy down the inheritance tree, the root definition of the inheritance sets it for the whole inheritance tree

Related

How to inherit and replace a #Entity from commons package?

I have an #Entity in a commons package:
#Entity("person")
public class Person {
//fields...
}
In an implementing application, I want to extend this entity with some custom fields.
But I still want to map to table person:
#Entity("person")
public class Person extends org.commons.Person {
//additional fields
}
Result:
Caused by: org.hibernate.DuplicateMappingException: The [Person] and [CustomPerson] entities
share the same JPA entity name: [person] which is not allowed
So how can I extend that entity and tell spring to somehow "forget" about the parent Person entity, so that only my CustomPerson is loaded?
The problem is that you are assigning the same name to both entities. You don't need to do that. You can annotate your parent entity with #Entity, #Table and #Inheritance (which by default employs single table inheritance) and your subclass entities with just #Entity:
#Entity
#Table("person")
#Inheritance
public class Person {
//fields...
}
#Entity
public class CustomPerson extends Person {
//additional fields
}

JPA tables inheritance and object mapping

Is it possible to map a baseTable with a base class and tell to JPA tool to not insert in the class the fileds that are in the baseTable?
I have the field creation-date which i want in every table of my db, so i created a baseTable with that field and the other tables extend this baseTable.
When i generate the classe for mapping this structure, japtool creates for me each table with creation-date field, which clearly i'd want just in baseEntity class and not in every child class.
There is a way to accomplish it?
If I understood your answer correctly, I think you are looking for JPA Inheritance
#MappedSuperclass
public class BaseEntity {
#Id
protected Integer id;
protected Date createdDate;
...
}
#Entity
public class EntityA extends BaseEntity {
protected String otherAttribs;
...
}
#Entity
public class EntityB extends BaseEntity {
protected Float differentAttribs ;
...
}

more name attributes in Table

Im my SQL Server Database I have 8 tables with the same structure.
Now I want to insert in selected tables with one Java class.
#Entity
#Table(name = "tbl_Prognosen") //here I want to put all table-Names
public class AZBNachricht { ...
is this possible?
It isn't possible to accomplish what you described.
The closest to code reuse at the entity class level would be to use a #MappedSuperclass class where you place all the shared column names, etc and then extend that for each table implementation with differing table names.
#MappedSuperclass
public abstract class AbstractStructure {
#Id
#GeneratedValue;
private Integer id;
private String column1;
private String column2;
}
#Entity
#Table(name = "table1")
public class Entity1 extends AbstractStructure {
}
// ... so on

How to annotate composition of abstract class instance?

I have a design of Person as shown in the following picture. The design is to allow a person to change his role from Staff to Student, Student to Faculty and so on.
I want to persist this system to DB using hibernate annotation. Does anyone know how to do that?
Thanks a lot!
So you have 1:N relation between Entity Persona and abstract entity Person Role. Think this may work for you.
#Entity
public class Person {
// Here you have all roles in some collection.
#OneToMany(mappedBy="person", fetch=FetchType.LAZY)
private List<PersonRole> roles;
...
}
#Entity
public abstract class PersonRole {
#ManyToOne
#JoinColumn(name="PERSON_ID")
private Person person;
...
}
#Entity
public class Staff extends PersonRole {
...
}
Also don't forget to set proper
#Inheritance(strategy=InheritanceType.<strategy>)
to define how class model is mapped to relational model.
Edit: Unfortunately #MappedSuperclass can't be used in relations mapping so this is not an option here as long as you would like to have PersonRole collection in Person entity.

JPA foreign key to multiple tables

We have a table in the database which has the following structure:
referenceId - int foreign key to various tables
tableReference - String defining the table
Is this good design, and is it somehow possible to map this relation?
This is very few information to advise you any solution, but JPA Joined Inheritance works something like that:
#Entity
#Inheritance(strategy=InheritanceType.JOINED)
#DiscriminatorColumn(name="PROJ_TYPE")
#Table(name="PROJECT")
public abstract class Project {
#Id
private long id;
...
}
#Entity
#DiscriminatorValue("L")
#Table(name="LARGEPROJECT")
public class LargeProject extends Project {
private BigDecimal budget;
}
#Entity
#DiscriminatorValue("S")
#Table(name="SMALLPROJECT")
public class SmallProject extends Project {
}
This will manage three tables in DB where the main table PROJECT which contain a column PROJ_TYPE to identify the target table.

Categories