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.
Related
I am a bit confused in regards to abstract classes and help would be great.
I have a the following classes
public abstract class AbstractUser{
private String username;
private String password;
}
And then I have this class
#Entity
public class Company extends AbstractUser{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String company_name
}
Now when I launch the application and I check the h2-console, the table Company only has the id and company_name. not the abstract classes variables. Is there a way to make it so it gets all the variables?
thank you in advance
You can use #MappedSuperclass Jpa annotation on the AbstractUser, Also consider moving the id attribute to the abstract class.
#MappedSuperclass
public abstract class AbstractUser{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
}
To resolve this, you will need JPA annotation on your abstract class. This is not specific to Spring Boot, it's JPA thing.
You can apply #MappedSuperclass on your abstract class and that should resolve this issue. Find More: Inherit Super Class Properties
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 saw similar questions, but answers weren't helpful. So, i get this error:
Use of #OneToMany or #ManyToMany targeting an unmapped class: com.podro.model.Journey.roadWay[com.podro.model.RoadElement]
I'm trying to create List with objects of RoadElements (which is interface for class Point and Section). There is any other way to do it? From what i know, i guess that is the only way to create proper mapping for this classes, and have list of this elements.
#Entity
#Table(name="Journey")
public class Journey {
// Some other fields
#Column(name="road_way")
#ManyToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
private List<RoadElement> roadWay;
}
#MappedSuperclass
public interface RoadElement {}
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#Table(name="Point")
public class Point implements RoadElement{
#Id
#Column(name="id")
#GeneratedValue(strategy= GenerationType.IDENTITY)
private int id;
private String name;
#Column(name="time_in_days")
private int timeInDays;
private Rate rating;
}
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#Table(name="Section")
public class Section implements RoadElement{
#Id
#Column(name="id")
#GeneratedValue(strategy= GenerationType.IDENTITY)
private int id;
#Column(name="section_name" , length=100)
private String sectionName;
#Column(name="time_in_days")
private int timeInDays;
#Column(name="kind_of_transport")
private Locomotion kindOfTransport;
}
Thanks for answers, I would be very grateful for help!
Associations are between entities. RoadElement is not an entity. It's an interface.
You may not do what you're trying to do. Hibernate needs to know the type of the entities contained in roadWay.
So, RoadElement should be a class, annotated with #Entity, having an ID that uniquely identifies a RoadElement among all the road elements (sections, points, etc.)
Section and Point should extend from RoadElement, and should NOT have their own ID, since it's inherited from RoadElement.
For reasons that were around before I got to this project, there are tables that are similar types but have different ID columns.
So, when I try this
#Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Element implements Serializable {
public String title;
}
#Entity
public class PrimaryElement extends Element {
#Id
long pid;
}
#Entity
public class OtherElement extends Element {
#Id
long oid;
}
But then I get an obvious error
No identifier specified for entity: Element
Now, I can't very well put the ID in the Element class because they are obviously mapped to different columns.
I have tried various flavors of #Id and 'abstract' and #MappedSuperClass and so on..
I am at a complete loss. Is there a way around this?
Any insights would be appreciated.
Thanks!
You can either replace the #Entity and #Inheritance annotations of your Element class by #MappedSuperclass (this annotation is responsible for technical mappings and only PrimaryElement and OtherElement will be fully featured entities) or move the oid field with it's #Id annotation to the class Element and use the #AttributeOverride annotation in it's subclasses to modify the column names (in this case also the abstract class Element will be a fully featured entity).
#AttributeOverride(name="oid", column=#Column(name="primary_element_id"))
UPDATE:
#MappedSuperclass
public abstract class Element implements Serializable {
#Id
private long id;
public String title;
}
#Entity
#AttributeOverride(name="id", column=#Column(name="pid"))
public class PrimaryElement extends Element {
}
#Entity
#AttributeOverride(name="id", column=#Column(name="oid"))
public class OtherElement extends Element {
}
I have 4 persistent classes which all have the same fields (exactly) the only 3 difference between them is 1) the class name, 2) the table name and 3) the data. i am aware that this might seem strange to some but trust me there is a good reason which i won't go into here.
now, i'm using hibernate annotations to configure my class which should work like so:
#Entity
#Table(name = "store")
public class Store
{
#Id
#Column(name = "unique_id")
protected String id;
#Column
protected String category;
...
}
.. and this does work, for a single stand-alone class, however there are many fields to map and i'd like to do it all in one hit for all four similar classes, ie:
public class StoreBase
{
#Id
#Column(name = "unique_id")
protected String id;
#Column
protected String category;
...
}
#Entity
#Table(name = "store1")
public class Store1 extends StoreBase
{}
#Entity
#Table(name = "store2")
public class Store2 extends StoreBase
{}
#Entity
#Table(name = "store3")
public class Store3 extends StoreBase
{}
#Entity
#Table(name = "store4")
public class Store4 extends StoreBase
{}
however when attempting this i get the following exception:
Caused by: org.hibernate.AnnotationException: No identifier specified for entity: package.entities.Store1
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:672)
at org.hibernate.cfg.AnnotationConfiguration.processArtifactsOfType(AnnotationConfiguration.java:546)
at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:291)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1292)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
i'm guessing this is because the super class is not being searched for the identifier?
is there a way to utilise inheritance in this context?
thanks, paul.
#MappedSuperclass
public class StoreBase
See docs for more info.
Have a look at #MappedSuperclass.