JPA subclass with #IdClass and no attributes - java

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!

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

Map JPA Embedded entity class id to Embeddable entity class id

I have a class:
#Entity
public class A {
#Embedded
#AttributeOverride(name = "id", column = #Column(name = "b_id"))
private B b;
}
There is column b_id BIGINT NOT NULL in table A
#Embeddable
#Entity
public class B {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
}
we are getting error: Caused by: org.hibernate.MappingException: component property not found: id
Basically, we need to map B in A using id
Kindly help
I think the problem is with #Id in embedded class. We can not use in an embedded class. Try removing that? If you can remove it, try using #EmbeddedId if you just need an id field.
Try this
#Entity
public class A implements Serializable {
private static final long serialVersionUID = 9154946919235019012L;
#Embedded
#AttributeOverride(name = "id", column = #Column(name = "b_id"))
private B b;
public A() {
}
public A(B b) {
this.b = b;
}
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
}
And here is class B
#Embeddable
#Entity
public class B implements Serializable {
private static final long serialVersionUID = 5579181803793008928L;
#Id
#Column(nullable = false)
private Long id;
public B(Long id) {
this.id=id;
}
public B(){
}
public void setId(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
}
You don't have getters and setters, or an additional constructor besides the implicit no arg one. You should have both a no-args constructor and getter and setter methods.

Remove redundant column for composite key in Hibernate

Hibernate creates empty "ID" column in case of code like in this post.
How tune it to not create "ID" column ("ID" is exact name of created column) or this can not be changed?
#Entity
#Table(name = "CATEGORY_RELATIONS")
public class CategoryRelations implements Serializable {
private CategoryRelationsPrimaryKey id;
#Id
#Column(name = "CATEGORY_RELATIONS_CATEGORY_ID")
private String categoryId;
#Id
#Column(name = "CATEGORY_RELATIONS_PARENT_ID")
private String parentId;
//getters and setters
#Entity
#IdClass(CategoryRelationsPrimaryKey.class)
public class CategoryRelationsPrimaryKey implements Serializable {
protected long categoryId;
protected long parentId;
//euqals, hashCode
}
}
1) #IdClass should stand at entity, not at composite id class;
2) If you already marked id properties by #Id, no separate id property is required:
#Entity
#Table(name = "CATEGORY_RELATIONS")
#IdClass(CategoryRelationsPrimaryKey.class)
public class CategoryRelations implements Serializable {
#Id
#Column(name = "CATEGORY_RELATIONS_CATEGORY_ID")
private String categoryId;
#Id
#Column(name = "CATEGORY_RELATIONS_PARENT_ID")
private String parentId;
//...
}
public class CategoryRelationsPrimaryKey implements Serializable {
protected String categoryId;
protected String parentId;
// ...
}
If you need some property named id, make it transient to avoid mapping to a DB table column.

JPA entity extends class contain #Id

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

Hibernate marker interface mapping using jpa

Hi I am new to hibernate and am facing problem in mapping marker interface.
I have a marker interface.
public interface Item{}
Then there are two classes which implement this interface:
public class Hotel implements Item{
private int id;
private String name;
private String location;
.......
}
public class Restaurant implements Item{
private int id;
private String name;
private String cuisine;
.......
}
There is another class which uses these two classes:
public class ItineraryItem {
private int id;
private Item item;
}
How can I map these classes using annotations.
Code:
#Entity
#Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class Item {
#Id
private int id;
}
#Entity
public class Hotel extends Item {
#Column
private String name;
#Column
private String location;
}
#Entity
public class Restaurant extends Item {
#Column
private String name;
#Column
private String cuisine;
}
#Entity
public class ItineraryItem {
#Id
private int id;
#JoinColumn
private Item item;
}
InheritanceType.TABLE_PER_CLASS will cause Hotel and Restaurant to have their own separate tables.
You can find more information here: http://en.wikibooks.org/wiki/Java_Persistence/Inheritance

Categories

Resources