Hibernate composite keys with abstract class - java

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,
}

Related

Spring JPA how to create an object with relationship to another entity in Application

I want to create a Person with an Address, each of them are an entity. My Entities seem to work, the part where i begin to struggle is on how to create a Person using the constructor where i also have to put in the Address.
personRepository.save(new Person(new Name("Test","Test"),new Adress("Street","Number","PLZ","Town"),LocalDate.parse("2000-01-01"),"email#email.com","911");
This sadly does not work so my question is how can i create a Person object with the Address.
I'm also wondering how i would add the address if i already got the address in my Address repository, is there a way to get the address or use the adress ID?
adresseRepository.save(new Adresse("Street","Number","PLZ","Town"));
Here's the code for both of the shortend.
Person:
#Entity
#Table(name = "Person")
public class Person {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "PersonID")
private Long personID;
#Column(name = "FullName")
#Convert(converter = NameConverter.class)
private Name fullName;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name="AdresseID")
private Adresse adresse;
#Column(name = "Geburtsdatum")
private LocalDate geburtsdatum;
#Column(name = "EMail")
private String email;
#Column(name = "Telefonnummer")
private String telefonnummer;
private Person() {}
public Person(Name fullName, Adresse adresse, LocalDate geburtsdatum, String email, String telefonnummer) {
this.fullName = fullName;
this.adresse = adresse;
this.geburtsdatum = geburtsdatum;
this.email = email;
this.telefonnummer = telefonnummer;
}
}
Address:
#Entity
#Table(name = "Adresse")
public class Adresse {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "AdresseID")
private Long adresseID;
#Column(name = "Strasse")
private String strasse;
#Column(name = "Hausnummer")
private String hausnummer;
#Column(name = "PLZ")
private String plz;
#Column(name = "Ort")
private String ort;
protected Adresse() {}
public Adresse(String strasse, String hausnummer, String plz, String ort) {
this.strasse = strasse;
this.hausnummer = hausnummer;
this.plz = plz;
this.ort = ort;
}
}
Ralationships are created in hibernate like this:
#Entity
#Table(name="CART")
public class Cart {
//...
#OneToMany(mappedBy="cart")
private Set<Item> items;
// getters and setters
}
Please note that the #OneToMany annotation is used to define the property in Item class that will be used to map the mappedBy variable. That is why we have a property named “cart” in the Item class:
#Entity
#Table(name="ITEMS")
public class Item {
//...
#ManyToOne
#JoinColumn(name="cart_id", nullable=false)
private Cart cart;
public Item() {}
// getters and setters
}
Soin your case you just have to add
#Entity
#Table(name = "address")
public class Address {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
//...
#OneToOne(mappedBy = "address")
private User user;
something lilke this to your Adress Table.
Because one Adress also have one user.
For more information visit this site

getting error " Error accessing field [private java.lang.Integer entity.AddressEntity.addressId] by reflection for persistent property "

I have two entity models named EmployeeEntity and AddressEntity. EmployeeEntity is in One to Many relationship with address entity. When I am inserting the data in EmployeeEntity it is throwing an error.
Error accessing field [private java.lang.Integer demo.entity.AddressEntity.addressId] by reflection for persistent property [demo.entity.AddressEntity#addressId] : demo.entity.AddressEntity#9fa01480
My AddressEntity is:
#Entity
#ToString
#Table(name = "address_entity")
public class AddressEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer addressId;
public Integer getAddressId() {
return addressId;
}
public void setAddressId(Integer addressId) {
this.addressId = addressId;
}
private String city;
private String state;
private String pinCode;
}
My EmployeeEntity is :
#Entity
#ToString
#Table(name = "employee_entity")
public class EmployeeEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer empId;
private String firstName;
private String lastName;
private String designation;
#OneToMany(cascade = CascadeType.ALL)
#JoinColumn(name="empId")
private List<AddressEntity> address;
}
My DAO method is:
public void addEmployee(Employee employee) {
// TODO Auto-generated method stub
EmployeeEntity employeeEntity=dozer.map(employee, EmployeeEntity.class);
entityManager.persist(employeeEntity);
}
My service method is :
public String addEmployee(Employee employee) {
employeeDao.addEmployee(employee);
return "Added Successfully";
}

Using a Spring Entity inside another Spring Entity

Getting the following error when I try to add a "Game" object to my ArrayList specified in my User class. This action was done in my controller class:
"org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.billsheng.huddlespringmvc.models.Game; nested exception is java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.billsheng.huddlespringmvc.models.Game"
User Entity
#Data
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String email;
private String firstName;
private String lastName;
private String password;
private String chosenTeam;
private int gamesPlayed;
private int gamesWon;
#ElementCollection
private List<Game> games = new ArrayList<>();
public User(String firstName, String lastName, String email, String password, String chosenTeam, int gamesPlayed, int gamesWon, ArrayList<Game> games) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.password = password;
this.chosenTeam = chosenTeam;
this.gamesPlayed = gamesPlayed;
this.gamesWon = gamesWon;
this.games = games;
}
public User(String firstName, String lastName, String email, String password, String chosenTeam) {
this(firstName, lastName, email, password, chosenTeam, 0, 0, null);
}
public User(int gamesPlayed, int gamesWon, ArrayList<Game> games) {
this.gamesPlayed = gamesPlayed;
this.gamesWon = gamesWon;
this.games = games;
}
public User() {
}
//getters and setters
}
Game Entity
#Data
#Entity
public class Game {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String homeTeam;
private String awayTeam;
private Date date;
private String location;
private String bettingOdds;
private boolean inProgress;
private boolean isReviewed;
//getters and setters
}
I did some research and I believe this issue stems from me using my Game object inside my User object but I'm not sure what the problem is specifically.
All help is appreciated.
#ElementCollection is not supposed to be used with collections of entities; it's used with collections of #Embeddable. If Thing is an entity, you don't use #ElementCollection, you use #OneToMany.
#ElementCollection:
Defines a collection of instances of a basic type or embeddable class
You can use #OneToMany mapping for establishing the relationship between User and Game entity.
User.java
#OneToMany(cascade=CascadeType.ALL,fetch= FetchType.LAZY,mappedBy = "user")
private List<Game> games = new ArrayList<>();
//getters and setters
Game.java
#ManyToOne
private User user;
//getters and setters

How to achieve Hibernate composite key relation?

I have clases which look something like this. I want to associate user with locality. Where there is a OneToMany relation between City-Locality. How to achieve this
public class User {
private Long userId;
private String email;
private String password;
private String firstName;
private String lastName;
private String phone;
}
#Entity
public class City {
#Id
private Long id;
private String cityName;
private String pinCode;
}
#Entity
public class Locality {
private Long Id;
private String localityName;
}
Your model lacks clarity a bit - there is no information about either city or locality in User entity. However, if you would add locality id field to user entity, solution will look like below:
#Entity
public class User {
#Id
private Long userId;
private String email;
private String password;
private String firstName;
private String lastName;
private String phone;
#OneToOne
#JoinColumn(name="LOCALITY_ID")
private Locality locality;
//setters/getters omitted
}
#Entity
public class City {
#Id
private Long id;
private String cityName;
private String pinCode;
#OneToMany
#JoinColumn(name="LOCALITY_ID") // join column is in table for LOCALITY
private Set<Locality> localities;
//setters/getters omitted
}

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

Categories

Resources