JPA entity extends class contain #Id - java

i have entities classes all contains id as primary key, can i create abstract class which contains all common fields and allow all classes extends this class as the following :
public abstract class CommonFields{
#Id
#Column(name = "ID")
private long id;
public void setId(long id) {
this.id = id;
}
public long getId() {
return id;
}
}
#Entity
#Table
public class B extends CommonFields{
String carModel;
}
#Entity
#Table
public class A extends CommonFields{
String name;
}
Thank You All

You can annotate the class with the common fields with #MappedSupperclass
#MappedSuperclass
public abstract class CommonFields{
#Id
#Column(name = "ID")
private long id;
public void setId(long id) {
this.id = id;
}
public long getId() {
return id;
}
}
From the #MappedSuperclass doc:
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.

Sure you can. With Hibernate, you can use three diffewrents implementations.
Use discriminators: Which #DiscriminatorValue Determine the entity type.
This case both entities share same table
#Entity
#Table(name = "PERSON")
#Inheritance(strategy=InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(
name="discriminator",
discriminatorType=DiscriminatorType.STRING
)
#DiscriminatorValue(value="P")
public abstract class Person {
#Id
#GeneratedValue
#Column(name = "PERSON_ID")
private Long personId;
#Column(name = "FIRSTNAME")
private String firstname;
#Column(name = "LASTNAME")
private String lastname;
// Constructors and Getter/Setter methods,
}
#Entity
#Table(name="PERSON")
#DiscriminatorValue("E")
public class Employee extends Person {
#Column(name="joining_date")
private Date joiningDate;
#Column(name="department_name")
private String departmentName;
// Constructors and Getter/Setter methods,
}
Or you can use a table per subclass:
#Entity
#Table(name = "PERSON")
#Inheritance(strategy=InheritanceType.JOINED)
public abstract class Person {
#Id
#GeneratedValue
#Column(name = "PERSON_ID")
private Long personId;
#Column(name = "FIRSTNAME")
private String firstname;
#Column(name = "LASTNAME")
private String lastname;
public Person() {
}
public Person(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
// Getter and Setter methods,
}
#Entity
#Table(name="EMPLOYEE")
#PrimaryKeyJoinColumn(name="PERSON_ID")
public class Employee extends Person {
#Column(name="joining_date")
private Date joiningDate;
#Column(name="department_name")
private String departmentName;
public Employee() {
}
public Employee(String firstname, String lastname, String departmentName, Date joiningDate) {
super(firstname, lastname);
this.departmentName = departmentName;
this.joiningDate = joiningDate;
}
// Getter and Setter methods,
}
You can find the rest of the details here http://viralpatel.net/blogs/hibernate-inheritance-table-per-subclass-annotation-xml-mapping/

Just add the CommonFields class as entity in the persistence.xml file.
EclipseLink / JPA Annotations – #MappedSuperclass

Related

getting error during the creation of relationship between JPA entities

I'm trying to create entities but I got the following error.
Internal Exception: Exception [EclipseLink-7157] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Entity class [class application.Team] must use a #JoinColumn instead of #Column to map its relationship attribute [mPlayers].
These are my entities, I need to store data into the database using the Java Persistence API (JPA). To do so I create entities as following. Maybe I have created the relationships between entities in the wrong way.
Person
#MappedSuperclass
public class Person {
#Id
#GeneratedValue( strategy= GenerationType.AUTO )
protected int p_id;
protected String firstName;
protected String middleName;
protected String lastName;
protected String phone;
protected String email;
public Person() {
}
}
Player
#Entity
#Table( name = "tbl_players")
#AttributeOverride(name="id", column=#Column(name="player_id"))
public class Player extends Person implements Serializable{
private int player_id;
#Column(name = "goals_in_year")
private int numberOfGoalsInCurrentYear;
private boolean goalie;
#Column(name = "defended_goals")
private int defendedGoals;
public Player(){
}
}
Manager
#Entity
#Table( name = "tbl_manager")
#AttributeOverride(name="id", column=#Column(name="manager_id"))
public class Manager extends Person implements Serializable{
private String dob;
private int starRating;
#OneToOne
private Team teamToManage;
public Manager(){
}
}
Team
#Entity
#Table( name = "tbl_team")
public class Team implements Serializable {
#Column(name = "team_name")
#Id
String teamName;
#OneToOne
Manager manager;
#Column(name = "team_players")
#OneToMany
private List<Player> mPlayers = new ArrayList<>();
#Column(name = "jersey_color")
String jerseyColor;
public Team(){
}
}
League
#Entity
public class League {
#Id
private int league_id;
#OneToMany
#Column(name = "League Teams")
private List<Team> mTeam = new ArrayList<>();
public void addTeam(Team team) {
mTeam.add(team);
}
public void removeTeam(Team team) {
mTeam.remove(team);
}
}
Use #JoinColumn for Mapping (#OneToMany, #ManyToMany, #ManyToOne) instead of #Column. #Column is used to specify the mapped column for a persistent property or field.
Player
#Entity
#Table( name = "tbl_players")
#AttributeOverride(name="id", column=#Column(name="player_id"))
public class Player extends Person implements Serializable{
private int player_id;
#Column(name = "goals_in_year")
private int numberOfGoalsInCurrentYear;
private boolean goalie;
#Column(name = "defended_goals")
private int defendedGoals;
#OneToOne // or #OneToMany as you desire
#JoinColumn(name="team_name") // here the name you have given to the column in tbl_players
private Team team;
public Player(){
}
}
Manager
#Entity
#Table( name = "tbl_manager")
#AttributeOverride(name="id", column=#Column(name="manager_id"))
public class Manager extends Person implements Serializable{
private String dob;
private int starRating;
#OneToOne(mappedBy="manager")
private Team teamToManage;
public Manager(){
}
}
Team
#Entity
#Table( name = "tbl_team")
public class Team implements Serializable {
#Id
#Column(name = "team_id")
private int id;
#Column(name = "team_name")
String teamName;
#OneToOne
#JoinColumn(name="manager_id")
Manager manager;
#Column(name = "team_players")
#OneToMany(mappedBy="team")
private List<Player> mPlayers = new ArrayList<>();
#Column(name = "jersey_color")
String jerseyColor;
#ManyToOne(mappedBy="")
private League league;
public Team(){
}
}
League
#Entity
#Table( name = "tbl_league")
public class League {
#Id
#Column(name="league_id")
private int league_id;
#OneToMany
#JoinTable(name="tbl_league_teams",joinColumns=#JoinColumn(name = "league_id"), inverseJoinColumns=#JoinColumn(name = "team_id"))
private List<Team> mTeam = new ArrayList<>();
public void addTeam(Team team) {
mTeam.add(team);
}
public void removeTeam(Team team) {
mTeam.remove(team);
}
}
Create new intermiditate mapping table named tbl_league_teams with columns league_id and team_id to facilitate the #JoinTable in League entity to map between teams in a league.
It seems to be due to #Column(name = "team_players") and #OneToManyPlease
Please read the link
https://stackoverflow.com/a/24206471/11207493
Why dont u treat each model class as an entity then u join the model using either ManyToOne or OneToMany

JPA retrieve entities relationships

I am trying to retrieve the list of all entities containing relations that references the specified entity.
"Role" Entity :
#Entity
#Table(name="Role")
#Access(AccessType.PROPERTY)
public class Role implements Serializable {
private String description;
private Long roleId;
#Column(name = "role_id")
#Id
public Long getRoleId() {}
#Column(name = "description")
public String getDescrition() {}
}
"User" Entity :
#Entity
#Table(name="users")
#Access(AccessType.PROPERTY)
public class User implements Serializable {
private Long userId;
private String name;
private Role role;
#Column(name = "user_id")
#Id
public Long getUserId() {}
#ManyToOne()
JoinColumn(name="role_id")
public Role getRole() {}
public String getName() {}
}
"Group" Entity :
#Entity
#Table(name="groups")
#Access(AccessType.PROPERTY)
public class User implements Serializable {
private Long groupId;
private String description;
private Role role;
#Column(name = "group_id")
#Id
public Long getGroupId() {}
#ManyToOne()
JoinColumn(name="role_id")
public Role getRole() {}
public String getDescription() {}
}
I need a that works like this :
List<Class<?>> entities = getEntityReferences(Role.class);
foreach (Class<?> entity : entities )
System.out.println(entity.getName());
The output would be :
User
Group
I think JPA use something like this for the bean validations or cascade mechanics but I can't find a simple way to achieve this.
The only way I found by now is to iterate through all the annotations of all the entities (returned by "entityManagerFactory.getMetamodel().getEntities()") to look for relations (ManyToOne, OneToOne ect.). It seems a bit tedious, I'm sure there's a better way to do it...
Thank you all...

QueryMethodParameterConversionException

I'm trying to access JPA Data with REST using spring-boot-starter-data-rest.
I want to use a different method than the CrudRepository has. But the framework responds with the following exception:
exception is org.springframework.data.repository.support.QueryMethodParameterConversionException: Failed to convert Brazil into hello.Country!] with root cause
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [#org.springframework.data.repository.query.Param hello.Country]
Endpoint
http://localhost:8080/rest/cities/search/findByCountry?name=Brazil
CityRepository.java
#RepositoryRestResource(collectionResourceRel = "cities", path = "cities")
public interface CityRepository extends CrudRepository<City, Long> {
List<City> findByCountry(#Param("name") Country country);
}
City.java
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
#Entity
#Table(name = "City")
public class City implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#JsonInclude(value=Include.ALWAYS)
private long id;
#NotNull
#Column(name="name")
private String name;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "country_id")
#Embedded
private Country country;
protected City() {}
public City(long id, String nome) {
this.id = id;
this.name = nome;
}
public Country getCountry() {
return country;
}
Country.java
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
#Entity
public class Country implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
#NotNull
#Column(name = "name")
private String name;
#OneToMany(fetch = FetchType.LAZY, mappedBy="country")
private Set<City> cities;
protected Country() {}
public Country(long id, String nome) {
this.id = id;
this.name = nome;
}
When I call http://localhost:8080/rest/cities/ , I get the list of cities normally. I setted the configureRepositoryRestConfiguration to config.setBasePath("/rest");
java.lang.String != hello.Country
In accordance with the documentation, we need to:
Use ResponseBody with consumes
Or create object from String like in REST hello world example
I did the following to resolve this issue, using a nativeQuery:
#Query(value = "SELECT * FROM City c JOIN Country co
ON c.country_id = co.id WHERE co.name
LIKE (CONCAT_WS('%',:name, '%'))", nativeQuery = true)
List<City> country(#Param("name") String name);

Hibernate composite keys with abstract class

Is it possible to have a Employee table with composit primary key (personID,departmentName) keeping
the Person's class #id annotation , also keeping as it is a abstract class.
public abstract class Person {
#Id
#GeneratedValue
#Column(name = "PERSON_ID")
private Long personId;
#Column(name = "FIRSTNAME")
private String firstname;
// Getter and Setter methods,
}
#Entity
#Table(name="EMPLOYEE")
#PrimaryKeyJoinColumn(name="PERSON_ID")
public class Employee extends Person {
#Column(name="joining_date")
private Date joiningDate;
#Column(name="department_name")
private String departmentName;
public Employee() {
}
public Employee(String firstname, String lastname, String departmentName, Date joiningDate) {
super(firstname, lastname);
this.departmentName = departmentName;
this.joiningDate = joiningDate;
}
// Getter and Setter methods,
}

JPA subclass with #IdClass and no attributes

I have a subclass Entity with no #Id or #Column attribute.
but my subclass entity has #IdClass as follows
#Entity
#Table(name = "Employee")
#IdClass(EmployeeEntityPK.class)
public class EmployeeEntity extends AbstractEntity {
#Override
public void setName(String name) {
super.setName(name);
}
#Override
public void setLocation(String location) {
super.setLocation(location);
}
#Override
public void setEmpId(Integer empId) {
super.setEmpId(empId);
}
}
When I try to deploy my project. I am getting exception from hibernate
Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.RangeCheck(ArrayList.java:547) [rt.jar:1.6.0_17]
at java.util.ArrayList.get(ArrayList.java:322) [rt.jar:1.6.0_17]
at org.hibernate.cfg.AnnotationBinder.getUniqueIdPropertyFromBaseClass(AnnotationBinder.java:2576)
at org.hibernate.cfg.AnnotationBinder.isIdClassPkOfTheAssociatedEntity(AnnotationBinder.java:925)
at org.hibernate.cfg.AnnotationBinder.mapAsIdClass(AnnotationBinder.java:824)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:671)
complete exception is in http://pastebin.com/SnhQ1ZVQ
Hibernate is trying to find #Id class from my Entity which is not there.
How can I resolve this issue.
My super class is as follows
#MappedSuperclass
public class AbstractEntity implements Serializable {
#Id
#Column(name = "empId")
private Integer empId;
#Column(name = "Name")
private String name;
#Column(name = "LOCATION")
private String location;
public Integer getEmpId() {
return empId;
}
//along with other getter setters
}
If I have a primary key with more than one column I use the normal #Id Property on the class I want to use as Pk. The Id-Class is annotated with #Embeddable...
example:
Entity:
#Entity
public class Foo extends AbstractEntity implements Serializable {
private static final long serialVersionUID = 1;
#EmbeddedId
private FooPK id;
//Getter, Setter...
}
EmbeddedId:
#Embeddable
public class FooPK implements Serializable {
private static final long serialVersionUID = 1;
private Integer firstId;
private Integer SecondId;
public FavoritenPK() {
}
// Setter, Getter...
}
EDIT:
I had troubles having the #Id in MappedSuperclass. Try not to put the #Id-Property in Mapped-Superclass!

Categories

Resources