I am creating two tables using Spring boot and JPA:
Apartment table:
id, name, address_id, website
Address table:
id, street_num, street, city, .....
the address_id should be the foreign key and pointing to id in address table.
I couldn't get my code working. Here are my two Entity classes:
Apartment.java:
#Entity
public class Apartment {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
#OneToOne(cascade = CascadeType.ALL)
#JoinTable(name = "address",
joinColumns = #JoinColumn(name = "apt_id"))
private Address address;
private String website;
//getters and setters
Address.java:
#Entity
public class Address {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private Integer apt_id;
private String streetNum;
private String street;
private String city;
private String state;
private String zipCode;
//getters and setters
what I am getting is an extra column called address_id in address table....and missing address_id in apartment table....
Many Thanks!
Hibernate one to one mapping with foreign key association
In this kind of association, a foreign key column is created in owner entity
The join column is declared with the #JoinColumn annotation which looks like the #Column annotation. It has one more parameters named referencedColumnName. This parameter declares the column in the targeted entity that will be used to the join.
Replace Your Apartment Class with this:
#Entity
public class Apartment {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "apt_id"))
private Address address;
private String website;
//getters and setters
Related
I have two tables: users and userdetails as follows:
package com.example.easynotes.model;
import javax.persistence.*;
import java.io.Serializable;
#Entity
#Table(name = "users")
#IdClass(UserID.class)
public class User implements Serializable {
#Id
int id;
#Id
String name;
String department;
//getters and setters
}
The userdetails classes will be this:
public class UserDetails implements Serializable{
int id;
String name;
String address;
String otherFields;
//getters and setters
}
id and name in users is a composite primary and I want the same fields in userdetails to be the foreign key. How can I achieve this in hibernate ?
We need to put both key in #Embeddable to detach compound key thenafter, put it in User Entity using #EmbeddedId and map both primary key using Hibernate Relational Mapping...
There are two option to Composite Primary Key:
Using #EmbeddedId
Using #IdClass()
Here down is example:
----------------------------------- Using EmbeddedId -----------------------------------
Compound primary key:
#Embeddable
public class UserIdName implements Serializable {
int id;
String name;
// getter and setter
}
User:
#Entity
#Table(name = "users")
public class USER{
#EmbeddedId
private UserIdName id;
String department;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private Set<Userdetail> userdetail;
// getter and setter
}
UserDetails:
#Entity
#Table(name = "Userdetail")
public class Userdetail {
#Id
private int detail_id;
#ManyToOne
#JoinColumns({ #JoinColumn(name = "id", referencedColumnName = "id"),
#JoinColumn(name = "name", referencedColumnName = "name") })
private USER user;
String address;
String otherFields;
// getter setter
}
----------------------------------- Using IdClass -----------------------------------
Compound primary key:
public class UserIdName implements Serializable {
int id;
String name;
// getter and setter
}
User:
#Entity
#Table(name = "users")
#IdClass(UserIdName.class)
public class USER{
#Id
int id;
#Id
String name;
String department;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private Set<Userdetail> userdetail;
// getter and setter
}
UserDetails:
#Entity
#Table(name = "Userdetail")
public class Userdetail {
#Id
private int detail_id;
#ManyToOne
#JoinColumns({ #JoinColumn(name = "id", referencedColumnName = "id"),
#JoinColumn(name = "name", referencedColumnName = "name") })
private USER user;
String address;
String otherFields;
// getter setter
}
-> If you wanna insert both foreign key manually try below code
Put this code in UserDetails
#ManyToOne
#JoinColumn(name = "id", referencedColumnName = "id", insertable = false, updatable = false)
#JoinColumn(name = "name", referencedColumnName = "name", insertable = false, updatable = false)
private USER user;
#Column(name="id")
private int id;
#Column(name="name")
private String name
// don't forget to put getter setter
User Table:
User Detail Table:
I have two entities User:
public class User {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long userID;
#Column(name = "userHashedPassword")
private String password;
#Column(name = "userName")
private String userName;
#Column(name = "userEmail")
private String email;
#Transient
private List<String> groups = new LinkedList<>();
#ManyToMany
#JoinTable(name = "UserRoles",
joinColumns = #JoinColumn(
name = "userID"),
inverseJoinColumns = #JoinColumn(
name = "roleID"))
private Set<Role> roles = new HashSet<>();
#OneToMany(mappedBy = "user")
private Set<Rating> ratings;
protected User(){}
public User(String userHashedPassword, String userName, String email, Set<Role> roles){
this.password = userHashedPassword;
this.userName = userName;
this.email = email;
this.roles = roles;
}
//getters and setters
}
And Group:
#Table(name="FocusGroups")
#Entity
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
property = "groupID")
public class Group {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long groupID;
private String groupName;
#ManyToMany
#JoinTable(name = "GroupMembers",
joinColumns = #JoinColumn(
name = "groupID"),
inverseJoinColumns = #JoinColumn(
name = "userID"))
private Set<User> groupMembers = new HashSet<>();
#ManyToOne(fetch = FetchType.EAGER, optional = true)
#JoinColumn(name="frameworkID", nullable = true)
private Framework framework;
public Group(){}
public Group(String groupName, Set<User> groupMembers, Framework framework) {
this.groupName = groupName;
this.groupMembers = groupMembers;
this.framework = framework;
}
//getters setters
}
When I delete a User, I want to remove them from group members, however it fails due to foreign key constraint: java.sql.SQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (capripol.groupmembers, CONSTRAINT FK98tbu0sjfsn1m5p340dn0v8wo FOREIGN KEY (userID) REFERENCES users (userID))
How do I work around this?
Well, I will try to answer: First of all, it is rather strange you refer on Groups in user
entity like that:
#Transient
private List<String> groups = new LinkedList<>();
It this case, you will not have a column group in user table in database, hence you have to first perform removal from group_members for an all groups:
delete from group_members where userid = <user_id_you_want_to_remove>;
And only after your JoinTable table does not contain any refers to user with <user_id_you_want_to_remove>, than you can execute
delete from users where userid = 1;
Note: there is no matter you do it by spring data (e.g. deleteById(Long id) and using #Query annotation specify the query above in SQL or HQL, up to you) - this will work. But I highly recommend you to reconsider you database structure - it is not cute to store only one entity.
I am working on below database tables :
users table - Each row represents a User in the system. It has a foreign key constraint to countries table.
countries table - Each row represents a Country and each country can have a list of dialects stored in table dialects.
I am using Spring data JPA and have created below entity classes
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "full_name")
private String fullName;
#Column(name = "createdAt")
private Date createdAt;
#Column(name = "country_code")
private Integer countryCode;
#Column(name = "dialect_key")
private String dialectKey;
}
public class Country {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer country_code;
#Column(name = "name")
private String name;
#Column(name = "continent_name")
private String continentName;
#ElementCollection
#CollectionTable(name = "Dialect", joinColumns = { #JoinColumn(name = "country_code") })
private List<Dialect> dialectList;
}
#Embeddable
public class Dialect {
private String name;
}
Now I have a use case where I need to fetch the full name and dialect name for a given User.
Select u.full_name, d.name from users u
join countries c on u.country_code = c.country_code
join dialects d on c.country_code = d.country_code
where u.id = :user_id and u.dialect_key = d.dialect_key
Question - The above query works fine when ran as a native query and returns a List of Object. Further I am mapping the Objects List to the List of POJO. Is there a better way to do this to avoid Object -> POJO conversion explicitly ?
How can I use the data send through post method, and save those data in a many to many relationship? I used #JsonIgnore annotation to stop the recursion.
I have implemented two entities.One is Employee and the other is Skills.In the Employee entity I used #JsonIgnore annotation to avoid the reccursion. But when I inserted the values Employee table got updated but the joining tabled is not updating.
This is my Employee entity class
#Entity
#Table(name = "Employee")
public class Employee implements Serializable{
private static final long serialVersionUID = -3009157732242241606L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long emp_id;
#Column(name = "emp_fname")
private String emp_fname;
#Column(name = "emp_lname")
private String emp_lname;
#Column(name = "emp_email")
private String emp_email;
#Column(name = "emp_dob")
private Date emp_dob;
#ManyToMany(cascade = CascadeType.MERGE)
#JoinTable(name = "emp_skills",
joinColumns = #JoinColumn(name = "emp_id", referencedColumnName = "emp_id"),
inverseJoinColumns = #JoinColumn(name = "s_id",referencedColumnName = "s_id"))
#JsonIgnore
private Set<Skills> skills;
}
This is my Skills class
#Entity
#Table(name = "Skills")
public class Skills implements Serializable {
private static final long serialVersionUID = -3009157732242241606L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long s_id;
#Column(name = "s_name")
private String s_name;
#ManyToMany(mappedBy = "skills")
private Set<Employee> employees;
And this is my controller class method to save data
#RequestMapping("/save")
#PostMapping("/save")
#CrossOrigin
public void createEmployee(#RequestBody Employee employee, BindingResult bindingResult){
Employee emp = new Employee(employee.getEmp_fname(),employee.getEmp_lname(),employee.getEmp_email(),employee.getEmp_dob());
emp.setSkills(employee.getSkills());
empRepository.save(emp);
//empRepository.save(new Employee(employee.getEmp_fname(),employee.getEmp_lname(),employee.getEmp_email(),employee.getEmp_dob()));
}
I want to update both Employee and emp_skills (the joining table) when the save method is triggered.
I have mapped a one to many relationship between a user and an admin as shown in the user class
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "userId")
private Long id;
#Column(nullable = false)
private String name;
#Column(unique = true, nullable = false)
private String email;
#Column(nullable = false)
private long timestamp;
#OneToOne
#JoinColumn(name = "adminId")
Admin admin;
Now I am trying to save a user by inserting a value of 1 to the adminId field in the users table using SessionFactory of hibernate as shown
public void save(User user) {
//User userAdmin = new User();
long id = 1 ;
user.setId(id);
getSession().save(user);
}
EDITTED
Considering getters and setters, these are the fields in the admin table
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "adminId")
private Long id;
#Column(nullable = false)
private String name;
#Column(nullable = true)
private String department;
My challenge is that when I save, nothing gets inserted (that is value of 1) on the adminId field referencing the admin foreign key in the users table.
Kindly assist!
You'll have to get the Admin entity with id 1 first and then set it on the new User:
#Transactional
public void save(User user) {
Admin admin = getSession.createQuery("from Admin a where a.id = ?)
.setParameter(0, 1);
user.setAdmin(admin);
getSession().save(user);
}