I'd like to map lots of subclasses with a common parent class : B extends A, C extends A,... but the database doesn't care A. And B and C have nothing in common (no Id, no reference...).
public class A {
#Id
#Column(name="id")
private Long id;
#Column(name="reference", nullable=false)
private String reference;
}
Is it possible to do this without adding #Entity ?
SOLUTION
#MappedSuperclass
public class A {
#Id
#Column(name="id")
private Long id;
#Column(name="reference", nullable=false)
private String reference;
}
#Entity
#Table(name="B")
public class B extends A {
}
Use #MappedSuperclass on class A:
Designates a class whose mapping information is applied to the entities that inherit from it. A mapped superclass has no separate table defined for it.
Related
I have this generic entity:
#MappedSuperclass
abstract class Position<T> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Enumerated(EnumType.STRING)
private T name;
}
But there's a case where the generic type is a String:
#Entity
class ChildPosition0 extends Position<String> {
}
And, JPA will complaint that String is not an enum in this case, but I need to annotate this name field if it's an enum, if not, the database will mark it as int type, and that's not ideal. How do I solve this? How to annotate the field conditionally?
My workaround:
Use Position as a parent class, and adding those field in child class individually, even though they share the same field:
#MappedSuperclass
abstract class Position {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
}
And extends it from child entity like this:
Child1:
#Entity
public class ChildPosition1 extends Position {
#Enumerated(EnumType.STRING)
private Priority name; // <- Priority is enum type
}
Child2:
#Entity
public class ChildPosition2 extends Position {
private String name;
}
This is too ugly IMO. And Java does not allow class field override from child class. So, back to the question: how to annotate generic field conditionally?
I am trying to implemet inheritance hierarchy as mentioned in below image using hibernate Joined strategy.
Since Joined strategy creates table for entity regardless of entity class is Concrete or Abstract.
I don't want to create separate table for "CompanyEmployee" so I declared it as mapped superclass, but I should able to query this class/subclasses in polymorphic way.
Since it is mapped superclass I can't do this, and if I declare it to be entity it will create table which I want to avoid.
So, is there any way I can achieve this? I am thinking about mixed inheritance but from below quote it doesn't seems to be a good solution.
Mixed Inheritance
We should begin this section by saying that the practice of mixing inheritance types within a single
inheritance hierarchy is currently outside the specification. We are including it because it is both useful
and interesting, but we are offering a warning that it might not be portable to rely on such behavior,
even if your vendor supports it.
Inheritance hierarchy
#Entity
#Table(name="j_employee")
#Inheritance(strategy=InheritanceType.JOINED)
#DiscriminatorColumn(name="emp_type", discriminatorType=DiscriminatorType.STRING)
public abstract class JEmployee extends AuditLog implements Serializable {
#Id
#Basic
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="employee_id")
private Integer employeeId;
#Basic
#Temporal(TemporalType.DATE)
#Column(name="join_date")
private Date joinDate;
#OneToOne
#JoinColumn(name="person_id", nullable=false)
private Person person;
#Column(name="emp_type", updatable=false, insertable=false)
private String empType;
//Getters and Setters
}
#Entity
#Table(name="j_contract_employee")
#DiscriminatorValue(value="JContractEmployee")
#PrimaryKeyJoinColumn(name="contract_employee_id", referencedColumnName="employee_id")
public class JContractEmployee extends JEmployee implements Serializable {
#Basic
#Column(name="daily_rate")
private Integer dailyRate;
#Basic
#Column(name="term")
private Integer term;
//Getters and Setters
}
//Don't want to create table for this class, but I should able to query this clas/subclasses in polymorphic way
#MappedSuperclass
public abstract class JCompanyEmployee extends JEmployee implements Serializable {
#Basic
#Column(name="vacation")
private Integer vacation;
//Getters and Setters
public Integer getVacation() {
return vacation;
}
public void setVacation(Integer vacation) {
this.vacation = vacation;
}
}
#Entity
#Table(name="j_part_time_employee")
#Access(AccessType.FIELD)
#DiscriminatorValue(value="JPartTimeEmployee")
#PrimaryKeyJoinColumn(name="part_time_employee_id", referencedColumnName="employee_id")
public class JPartTimeEmployee extends JCompanyEmployee implements Serializable {
#Basic
#Column(name="hourly_rate")
private Integer hourlyRate;
//Getters and Setters
}
#Entity
#Table(name="j_full_time_employee")
#Access(AccessType.FIELD)
#DiscriminatorValue(value="JFullTimeEmployee")
public class JFullTimeEmployee extends JCompanyEmployee implements Serializable {
#Basic
#Column(name="salary")
private Integer salary;
#Basic
#Column(name="penion")
private Integer pension;
//Getters and Setter
}
I have problem with JPA Entity Mappings. I have some classes:
ClassA
#Entity
public class ClassA {
private int id;
#OneToMany
private List<ClassB> listClassB;
}
ClassB
#Entity
public class ClassB {
private int id;
#ManyToOne
private ClassA classA;
#OneToMany
private List<ClassC> listClassC;
}
ClassC
#Entity
public class ClassC {
private int id;
#ManyToOne
private ClassB classB;
private String code;
private String name;
#OneToMany
private List<ClassD> listClassD;
}
ClassD
#Entity
public class ClassD {
private int id;
private Long value;
private Date startDate;
private Date finishDate;
#ManyToOne
private ClassC classC;
}
Now, I want to have another entity that have all the property and association of ClassC, and have it's own property (the value is numbers of ClassD that related to Class C). When I use class inheritance like this:
ClassE
#Entity
public Class ClassE extends ClassC {
// All ClassC properties
private Long numberOfClassD;
}
It throw com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'pegawai0_.DTYPE' in 'field list'.
"Maybe" caused by missing Discriminator column. But in my case, I don't have discriminator column.
* How to solved this issue ?*
Can I still use Class Inheritance? Or another way to solve this?
Thanks.
In the example, both ClassC & ClassE have been marked with #Entity and hence the 'Table per class hierarchy' inheritance strategy is used. By default, the discriminator column name is 'DTYPE'.
You can just try it out with using 'Table per class' hierarchy strategy on 'ClassC'. The tables generated, however, would be much different from the 'Table per class hierarchy' though.
You might want to check which inheritance strategy you would need based on the domain model. This link would be good guide to that:
http://docs.jboss.org/hibernate/orm/4.2/manual/en-US/html/ch10.html
Like Alan Hay suggest in the comment, the ClassC and ClassE doesn't have any relationship in database. So, using #MappedSuperclass solve the problem.
I implement it this way:
#MappedSuperclass
public Class SuperClass {
private int id;
#ManyToOne
private ClassB classB;
private String code;
private String name;
#OneToMany
private List<ClassD> listClassD;
}
#Entity
#Table(name = "table_name")
public Class ClassC extends SuperClass {
// No Property
}
#Entity
#Table(name = "table_name")
public Class ClassE extends SupperClass {
private String classECustomValue;
}
I am experiencing NPEs with some embedded JPA metamodel fields using Hibernate 4.3.5.Final.
Specifically, I have the following situation:
#Entity class A
#Embedded class B in class A
#Embedded class C extending class B
I am not getting the 'Unable to locate static metamodel field...' error on startup which seems common in these situations, however all of C_'s fields are null.
Pertinent chunks of my code, simplified for legibility are:
#Entity
#Table(name = "...")
public class A extends AbstractA {
// Attempting to define override in superclass
#AttributeOverride(name = "cField", column = #Column(name = "SOME_FIELD"))
#Embedded
private B b;
...
}
#Embeddable
#Access(AccessType.FIELD)
public class B extends C {
#Column(name="SOMETHING")
private String bField;
...
}
#Embeddable
#Access(AccessType.FIELD)
public abstract class C implements Serializable {
private static final long serialVersionUID = 1L;
private String cField;
...
}
In this example, C_.cField is null.
The corresponding generated metamodel classes for the embedded classes are:
#Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
#StaticMetamodel(B.class)
public abstract class B_ extends C_ {
public static volatile SingularAttribute<B, String> bField;
}
#Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
#StaticMetamodel(B.class)
public abstract class C_ {
// This object is null
public static volatile SingularAttribute<C, String> cField;
}
Unless I've just mucked something up, a key question which I haven't seen answered is - can an embeddable class extend another embeddable class? I've got it working using association rather than inheritance - namely, having C as an an #Embedded field in B - but I'd prefer inheritance if possible.
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.