OneToMany between 2 classes with Hibernate - java

I'm trying to get the hang of Hibernate.
After getting my project to compile, I've started to convert my classes to be "Hibernate-enabled"
Currently, I'm having 2 classes
1) Person (id, name, firstname, ...)
2) Task (Id, name, description, idOwner)
I would like to have a OneToMany relationship between Person(id) and Task (idOwner)
So when the users gets the List from the Person class, they would get all the tasks linked to that.
After some trying and failing, here's my current code:
Person.java
#Entity
#Table(name = "people", uniqueConstraints = {
#UniqueConstraint(columnNames = "PERSON_ID")
})
public class Person implements Serializable {
private int id;
private String firstName;
private String name;
private String function;
private String email;
private String password;
private RoleEnum role;
private List<Task> lstTasks;
public Person(String firstName, String name, String function) {
this.firstName = firstName;
this.name = name;
this.function = function;
this.email = "";
this.password = "";
this.setRole(RoleEnum.User);
}
// <editor-fold defaultstate="collapsed" desc="Getters">
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "PERSON_ID", unique = true, nullable = false)
public int getId() {
return id;
}
#Column(name = "PERSON_FIRSTNAME", unique = false, nullable = false, length = 30)
public String getFirstName() {
return firstName;
}
#Column(name = "PERSON_NAME", unique = false, nullable = false, length = 30)
public String getName() {
return name;
}
#Column(name = "PERSON_FUNCTION", unique = false, nullable = false, length = 30)
public String getFunction() {
return function;
}
#Column(name = "PERSON_EMAIL", unique = false, nullable = false, length = 30)
public String getEmail() {
return email;
}
#Column(name = "PERSON_PASSWORD", unique = false, nullable = false, length = 30)
public String getPassword() {
return password;
}
#Column(name = "PERSON_ROLE", unique = false, nullable = false, length = 30)
public RoleEnum getRole() {
return role;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "idOwner")
public List<Task> getLstTasks() {
return lstTasks;
}
//Setters
}
Task.java
#Entity
#Table(name="tasks", uniqueConstraints =
#UniqueConstraint(columnNames = "TASK_ID"))
public class Task implements Serializable {
private int id;
private String name;
private String description;
private int idOwner;
public Task(int id, String name, int idOwner) {
this.id = id;
this.name = name;
this.idOwner = idOwner;
}
// <editor-fold defaultstate="collapsed" desc="Getters">
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "TASK_ID", unique = true, nullable = false)
public int getId() {
return id;
}
#Column(name = "TASK_NAME")
public String getName() {
return name;
}
#Column(name = "TASK_DESCRIPTION")
public String getDescription() {
return description;
}
#Column(name = "TASK_ID_OWNER")
public int getIdOwner() {
return idOwner;
}
// </editor-fold>
//Setters
}
Can somebody tell/show/explain me what I have to do exactly, to make this work?

Currently your mapping should linking ownerId instead of Task class.
Change your Task class to this
private Person person;
#ManyToOne
#JoinColumn(name = "TASK_ID_OWNER")
public Person getPerson() {
return person;
}

In your Person entity you have declared one-to-many relationship with Task entity like this:
#OneToMany(fetch = FetchType.LAZY, mappedBy = "idOwner")
public List<Task> getLstTasks() {
return lstTasks;
}
Here you have given idOwner to mappedBy attribute, it means you are telling hibernate that there is property in Task class called idOwner which is of type Person.
So you have to modify your Tasks class like this (Changing the variable type from int to Person):
private Person idOwner;
#ManyToOne
#JoinColumn(name = "TASK_ID_OWNER")
public Person getIdOwner() {
return idOwner;
}
public void setIdOwner(Person idOwner) {
this.idOwner=idOwner;
}
If you remove the #JoinColumn annotation then hibernate will create a Join table for your relationship, else it will just create a foreign key in Task table with foreign key column name as TASK_ID_OWNER.

Related

Spring is not using ManyToMany relationship

I have a user and a movie model:
user:
#Entity(name = "User")
#Table(name = "USER")
public class User {
#Id
#Column(name = "ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_seq")
#SequenceGenerator(name = "user_seq", sequenceName = "user_seq", allocationSize = 1)
private Long id;
#Column(name = "USERNAME", length = 50, unique = true)
#NotNull
#Size(min = 4, max = 50)
private String username;
#Column(name = "PASSWORD", length = 100)
#NotNull
#Size(min = 4, max = 100)
private String password;
#Column(name = "FIRSTNAME", length = 50)
#NotNull
#Size(min = 4, max = 50)
private String firstname;
#Column(name = "LASTNAME", length = 50)
#NotNull
#Size(min = 4, max = 50)
private String lastname;
#Column(name = "EMAIL", length = 50)
#NotNull
#Size(min = 4, max = 50)
private String email;
#Column(name = "ENABLED")
#NotNull
private Boolean enabled;
#Column(name = "LASTPASSWORDRESETDATE")
#Temporal(TemporalType.TIMESTAMP)
#NotNull
private Date lastPasswordResetDate;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(
name = "USER_AUTHORITY",
joinColumns = {#JoinColumn(name = "USER_ID", referencedColumnName = "ID")},
inverseJoinColumns = {#JoinColumn(name = "AUTHORITY_ID", referencedColumnName = "ID")})
private List<Authority> authorities;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Boolean getEnabled() {
return enabled;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public List<Authority> getAuthorities() {
return authorities;
}
public void setAuthorities(List<Authority> authorities) {
this.authorities = authorities;
}
public Date getLastPasswordResetDate() {
return lastPasswordResetDate;
}
public void setLastPasswordResetDate(Date lastPasswordResetDate) {
this.lastPasswordResetDate = lastPasswordResetDate;
}
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "user_movie",
joinColumns = #JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "movie_id", referencedColumnName = "id")
)
private Set<Movie> movies;
public Set<Movie> getMovies() {
return movies;
}
public void setMovies(Set<Movie> movies) {
this.movies = movies;
}
}
movie:
#Entity(name = "Movie")
#Table(name = "movie")
public class Movie {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
public Movie(){}
public Movie(Integer id, String name ) {
this.id = id;
this.name = name;
}
#ManyToMany(mappedBy = "movies")
private Set<User> users;
public Set<User> getUsers() {
return users;
}
public void addUser(User user){
System.out.println("ADD MOVIE: " + user);
users.add(user);
user.getMovies().add(this);
}
public void setUsers(Set<User> users) {
this.users = users;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString(){
return "id: " + id + "name: " + name;
}
}
I've set up a many to many relation between these models. With, if I am correct, the user as the owner of the relation.
In my MovieController.java I have:
#RequestMapping(value = "/", method = RequestMethod.POST)
public Movie createMovie(#RequestBody Movie movie){
return movieService.createMovie(movie);
}
This calls the MovieService.java:
#Override
public Movie createMovie(Movie movie) {
return movieRepository.save(movie);
}
And this calls the MovieRepository.java:
#Repository
public interface MovieRepository extends CrudRepository<Movie, Serializable> {}
When I call the post methode from my front-end a movie record is saved in my movie table, but no record is created in the user_movie table. Doesn't Hibernate do this implicit since I set up a Many to Many relation between user and movie?
For the first view, your code is correct.
The problem can be in GenerationType.SEQUENCE (try to use GenerationType.AUTO for User's id), or you need to add #Transactional to your controller.
You save the movie and in order to also have the user saved the cascade has to be set in the movie. Otherwise you can keep the cascade in user and save him.
You need to put the cascade to the entity on which you call save to cascade it.
Movie{
#ManyToMany(mappedBy = "movies", cascade={CascadeType.ALL})
private Set<User> users;
public Set<User> getUsers() {
return users;
}
}
User {
#ManyToMany
#JoinTable(name = "user_movie",
joinColumns = #JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "movie_id", referencedColumnName = "id")
)
private Set<Movie> movies;
}
Don't forget to add the user to movie and vice versa before saving.
As with all bi-directional relationships it is your object model's and application's responsibility to maintain the relationship in both direction. There is no magic in JPA, if you add or remove to one side of the collection, you must also add or remove from the other side, see object corruption. Technically the database will be updated correctly if you only add/remove from the owning side of the relationship, but then your object model will be out of synch, which can cause issues.
see here: https://en.wikibooks.org/wiki/Java_Persistence/ManyToMany

How to persist entity with joining?

I am confused about how to save entry in db with column's join. I have #Entity bellow
#XmlRootElement
#XmlAccessorType(value = XmlAccessType.FIELD)
#Entity
#Table(name = "psc_users")
#NamedQuery(name = "User.findAll", query = "SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 8885916014620036457L;
#Id
private static final String SEQUENCE_NAME = "psc_users_user_id_seq";
#Id
#GeneratedValue(generator = "UseExistingOrGenerateIdGenerator",
strategy = GenerationType.SEQUENCE)
#GenericGenerator(name = "UseExistingOrGenerateIdGenerator",
strategy = "com.psc.util.UseExistingOrGenerateIdGenerator",
parameters = {
#org.hibernate.annotations.Parameter(name = "sequence", value = SEQUENCE_NAME)
}
)
#Column(name = "USER_ID")
private Long userId;
#Column(name = "DEF", length = 30)
private String def;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "DEL_DATE")
private Date delDate;
#Column(name = "DISPLAY_DEF", length = 60)
private String displayDef;
#Column(name = "EMAIL", length = 60)
private String email;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "NAVI_DATE")
private Date naviDate;
#Column(name = "NAVI_USER")
private String naviUser;
#Column(name = "PHONE", length = 30)
private String phone;
#Column(name = "PWD", length = 40)
private String pwd;
//bi-directional many-to-one association to Branch
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumn(name = "BRNC_BRNC_ID", nullable = false)
private Branch pscBranch;
public Long getBrncBrncId() {
return brncBrncId;
}
public void setBrncBrncId(Long brncBrncId) {
this.brncBrncId = brncBrncId;
}
#Column(name = "BRNC_BRNC_ID", insertable = false, updatable = false)
private Long brncBrncId;
//bi-directional many-to-one association to User
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumn(name = "CURATOR_USER_ID")
private User pscUser;
public Long getCuratorUserId() {
return curatorUserId;
}
public void setCuratorUserId(Long curatorUserId) {
this.curatorUserId = curatorUserId;
}
#Column(name = "CURATOR_USER_ID", insertable = false, updatable = false)
private Long curatorUserId;
public User() {
}
public Long getUserId() {
return this.userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getDef() {
return this.def;
}
public void setDef(String def) {
this.def = def;
}
public Date getDelDate() {
return this.delDate;
}
public void setDelDate(Date delDate) {
this.delDate = delDate;
}
public String getDisplayDef() {
return this.displayDef;
}
public void setDisplayDef(String displayDef) {
this.displayDef = displayDef;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getNaviDate() {
return this.naviDate;
}
public void setNaviDate(Date naviDate) {
this.naviDate = naviDate;
}
public String getNaviUser() {
return this.naviUser;
}
public void setNaviUser(String naviUser) {
this.naviUser = naviUser;
}
public String getPhone() {
return this.phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getPwd() {
return this.pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public Branch getPscBranch() {
return this.pscBranch;
}
public void setPscBranch(Branch pscBranch) {
this.pscBranch = pscBranch;
}
public User getPscUser() {
return this.pscUser;
}
public void setPscUser(User pscUser) {
this.pscUser = pscUser;
}
}
if I save User instance without field pscUser (here null) but there is valid CuratorUserId with correct value I end up in a situation with empty CuratorUserId in db. If you look at code then you will see these bound fields.
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumn(name = "CURATOR_USER_ID")
private User pscUser;
#Column(name = "CURATOR_USER_ID", insertable = false, updatable = false)
private Long curatorUserId;
code to save user
repositoryUser.save(user);
this i see in debugger
this i see in database after saving my user.
sorry for my stupid question but I come across on a different behavior, there is code in my project which behaves in another manner. I don't want to search actual another user(curator) for saving my user, because of overhead on query
The #Column annotation on the curetorUserId field has properties
insertable=false and updatable=false, which means that its value is ignored during inserts and updates.
You can either change these properties to true (but it can break your application in some other places) or just fill in pscUser field using EntityManager.getReference, which just creates a proxy and doesn't actualy produce a query to the database.
Your mapping should look like the below:
#XmlRootElement
#XmlAccessorType(value = XmlAccessType.FIELD)
#Entity
#Table(name = "psc_users")
#NamedQuery(name = "User.findAll", query = "SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 8885916014620036457L;
#Id
private static final String SEQUENCE_NAME = "psc_users_user_id_seq";
#Id
#GeneratedValue(generator = "UseExistingOrGenerateIdGenerator",
strategy = GenerationType.SEQUENCE)
#GenericGenerator(name = "UseExistingOrGenerateIdGenerator",
strategy = "com.psc.util.UseExistingOrGenerateIdGenerator",
parameters = {
#org.hibernate.annotations.Parameter(name = "sequence", value = SEQUENCE_NAME)
}
)
#Column(name = "USER_ID")
private Long userId;
#Column(name = "DEF", length = 30)
private String def;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "DEL_DATE")
private Date delDate;
#Column(name = "DISPLAY_DEF", length = 60)
private String displayDef;
#Column(name = "EMAIL", length = 60)
private String email;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "NAVI_DATE")
private Date naviDate;
#Column(name = "NAVI_USER")
private String naviUser;
#Column(name = "PHONE", length = 30)
private String phone;
#Column(name = "PWD", length = 40)
private String pwd;
//bi-directional many-to-one association to Branch
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumn(name = "BRNC_BRNC_ID", nullable = false)
private Branch pscBranch;
//bi-directional many-to-one association to User
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumn(name = "CURATOR_USER_ID")
private User pscUser;
public User() {
}
}
You need to think in terms of objects. The FK will only be set in the database if you set the pscUser reference to an instance of a User. If this is an existing User then you need to set a reference to the existing persistent entity.
Real answer is that I have two points for saving and updating my entity. Please see this Hibernate: Where do insertable = false, updatable = false belong in composite primary key constellations involving foreign keys?

Hibernate Exception when using mappedby attribute

I am trying to map between tables in pojo class.But I am getting exception for one attribute.
Pojo Classes
Users:
#Entity
#Table(name = "Users")
public class Users implements java.io.Serializable {
private int userId;
private Role role;
private Groups groupId;
private UserType userType;
private String userName;
private Boolean isActive;
public Users() {
}
public Users(int userId, Role role, Groups groupId ,UserType userType, String userName, boolean isActive) {
this.userId = userId;
this.role = role;
this.groupId = groupId;
this.userType = userType;
this.userName = userName;
this.isActive = isActive;
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "UserID", unique = true, nullable = false)
public int getUserId() {
return this.userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "RoleID", nullable = false)
public Role getRole() {
return this.role;
}
public void setRole(Role role) {
this.role = role;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "GroupId", nullable = false)
public Groups getGroup() {
return this.groupId;
}
public void setGroup(Groups group) {
this.groupId = group;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "UserTypeID", nullable = false)
public UserType getUserType() {
return this.userType;
}
public void setUserType(UserType userType) {
this.userType = userType;
}
#Column(name = "UserName", nullable = false)
public String getUserName() {
return this.userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
#Column(name = "IsActive", nullable = false, columnDefinition = "BIT")
public Boolean isIsActive() {
return this.isActive;
}
public void setIsActive(Boolean isActive) {
this.isActive = isActive;
}
}
Groups:
#Entity
#Table(name = "Groups")
public class Groups implements java.io.Serializable{
private int groupId;
private String groupName;
private String groupDesc;
private Set<Users> users = new HashSet<Users>(0);
public Groups (){
}
public Groups(int groupId, String groupName, String groupDesc){
super();
this.groupId = groupId;
this.groupName = groupName;
this.groupDesc = groupDesc;
}
public Groups(int groupId, String groupName, String groupDesc, Set<Users> users) {
super();
this.groupId = groupId;
this.groupName = groupName;
this.groupDesc = groupDesc;
this.users = users;
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name ="GroupID", nullable = false)
public int getGroupId() {
return groupId;
}
public void setGroupId(int groupId) {
this.groupId = groupId;
}
#Column(name = "GroupName", nullable = false)
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
#Column(name = "GroupDesc", nullable = false)
public String getGroupDesc() {
return groupDesc;
}
public void setGroupDesc(String groupDesc) {
this.groupDesc = groupDesc;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "groupId") //Error
public Set<Users> getUserse() {
return this.userse;
}
public void setUserse(Set<Users> users) {
this.users = users;
}
}
I am mapping the correct member variable of Users class. But I am getting exception like this
org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.project.pojo.Users.groupId in com.project.pojo.Groups.users
In users pojo I have attributes like role,usertype which are mapped without any exception.Whereas for group I am getting this exception.
Can someone please help me to resolve this exception.
Thank you :)
There is a problem in your member variables of classes users and groups
Change the variable name groupId to group of Users.pojo and change mappedby attribute to group in groups class set method.
This will resolve your problem.
In your Groups class, you first declared a variable named users as a set of Users, which is fine. So if you gonna annotate #OneToMany on your setters, the name must match the variable name.
Also, in your Users table, you created a Groups variable and you named it as groupId, but in your Users table you have a int type named groupId, this will confuse the heck out of hibernate and causing problems. You should rename it to:
private Groups group;
So it should be like:
#OneToMany(fetch = FetchType.LAZY, mappedBy = "group")
public Set<Users> getUsers() {
return this.users;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "group", nullable = false)
public Groups getGroup() {
return this.group;
}
You didn't ask but you need to fix your RoleID table also. I don't think you really understand how hibernate ORM works yet, see this:
http://www.mkyong.com/hibernate/hibernate-one-to-many-relationship-example-annotation/
It must be because of difference between users and userse.
You defined getter for the Group object in Users bean as:
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "GroupId", nullable = false)
public Groups getGroup() {
return this.groupId;
}
which is not the best accessor name for a bean.
Try renaming the Group object in Users from groupID to group and change the mapping annotation into something like:
#OneToMany(fetch = FetchType.LAZY, mappedBy = "group")
public Set<Users> getUserse() {
return this.userse;
}

JPA incompatible mapping in ManyToMany relationship. Cardinality does not correspond with the cardinality of its backpointer

The eclipse link throws the following error during app initialization
I cannot find the reason, despite the thorough search here.
This is the Error:
Caused by: Exception [EclipseLink-7244]
(Eclipse Persistence Services - 2.6.1.qualifier): org.eclipse.persistence.exceptions.ValidationException
Exception Description:
An incompatible mapping has been encountered between [class User] and [class UserAuthProvider]. This usually occurs when the cardinality of a mapping does not correspond with the cardinality of its backpointer.
at org.eclipse.persistence.exceptions.ValidationException.invalidMapping(ValidationException.java:1296)
at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ManyToManyAccessor.process(ManyToManyAccessor.java:158)
at org.eclipse.persistence.internal.jpa.metadata.MetadataProject.processNonOwningRelationshipAccessors(MetadataProject.java:1628)
at org.eclipse.persistence.internal.jpa.metadata.MetadataProject.processStage3(MetadataProject.java:1917)
at org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor.processORMMetadata(MetadataProcessor.java:577)
at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processORMetadata(PersistenceUnitProcessor.java:604)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1943)
... 48 more
My Classes.
User
#Entity
#Table(name = "users")
#XmlRootElement
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 255)
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
#Id
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 255)
#Column(name = "username")
private String username;
#Size(max = 512)
#Column(name = "password")
private char[] password;
#Column(name = "enabled")
private Boolean enabled;
#ManyToOne
#JoinColumn(name = "user_role")
private Role role;
#ManyToMany(mappedBy = "users")
private Collection<UserAuthProvider> authProviders;
#OneToOne(mappedBy = "user", cascade = CascadeType.PERSIST)
#NotNull
private UserInfo userInfo;
#Column(name = "firstname")
private String firstName;
#Column(name = "lastname")
private String lastName;
#Column(name = "displayname")
private String displayName;
#Column(name = "gender")
private Gender gender;
#Column(name = "address", length = 512)
private String address;
#Column(name = "address_geo", length = 512)
private String addressGeo;
#Temporal(javax.persistence.TemporalType.DATE)
#Column(name = "birthdate")
private Date birthDate;
#Temporal(javax.persistence.TemporalType.DATE)
#Column(name = "date_created")
private Date dateCreated;
#Temporal(javax.persistence.TemporalType.DATE)
#Column(name = "date_modified")
private Date dateModified;
public enum Gender {
MALE, FEMALE, UNKNOWN
}
public User() {
gender = Gender.UNKNOWN;
Locale greekLocale = new Locale("el");
dateCreated = Calendar.getInstance(greekLocale).getTime();
enabled = true;
authProviders = new HashSet<>();
userInfo = new UserInfo(this);
}
public User(String username) {
this();
this.username = username;
}
public User(String username, char[] password) {
this();
this.username = username;
this.password = password;
}
//getters and setters
#Override
public int hashCode() {
int hash = 0;
hash += (username != null ? username.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof User)) {
return false;
}
User other = (User) object;
if ((this.username != null && other.username != null) && (this.username.equals(other.username))) {
return true;
}
return true;
}
}
UserAuthProvider
#Entity
#Table(name = "user_auth_provider")
#XmlRootElement
public class UserAuthProvider implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Long id;
#Basic(optional = false)
#Column(name = "providername")
private String providerName;
#Basic(optional = true)
#ManyToMany
#JoinTable(
name = "auth_providers_per_user",
joinColumns = {
#JoinColumn(name = "auth_provider_id", referencedColumnName = "id")},
inverseJoinColumns = {
#JoinColumn(name = "username", referencedColumnName = "username")})
private Collection<User> users;
#Temporal(javax.persistence.TemporalType.DATE)
#Column(name = "date_created")
private Date dateCreated;
#Temporal(javax.persistence.TemporalType.DATE)
#Column(name = "date_modified")
private Date dateModified;
#Column(name = "enabled")
private Boolean enabled;
public UserAuthProvider() {
Locale greekLocale = new Locale("el");
dateCreated = Calendar.getInstance(greekLocale).getTime();
users = new HashSet<>();
enabled = true;
}
#Override
public int hashCode() {
int hash = 5;
hash = 11 * hash + Objects.hashCode(this.id);
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final UserAuthProvider other = (UserAuthProvider) obj;
if (!Objects.equals(this.id, other.id)) {
return false;
}
return true;
}
}
Any help would be valuable, thank you
Remove #Basic from all of your association mappings. #Basic is intended to be used with primitive fields. From http://en.wikibooks.org/wiki/Java_Persistence/Basic_Attributes
A basic attribute is one where the attribute class is a simple type such as String, Number, Date or a primitive. A basic attribute's value can map directly to the column value in the database.

Saving the foreign key in a hibernate

I have two tables 1. User 2. USersLocation, In the location table I use the userId as foreign key. When I save the location object in database I want to save the current user Id as well in the table.
What I have tried so far is
SocialLogin Controller
SocialAuthManager manager = socialAuthTemplate.getSocialAuthManager();
AuthProvider provider = manager.getCurrentAuthProvider();
Profile userProfile = provider.getUserProfile();
Location Controller
UsersLocation location = new UsersLocation();
location.setSourceLat(SOURCE_LATITUDE);
location.setSourceLng(SOURCE_LONGITUDE);
location.setDestinationLat(DEST_LATITUDE);
location.setDestinationLng(DEST_LONGITUDE);
location.setUserId((User) WebUtils.getSessionAttribute(request, "userId"));
placesService.saveLocaion(location);
The Userslocation class is
#Entity
#Table(name = "locations")
public class UsersLocation implements Serializable{
private static final long serialVersionUID = 1L;
private double sourceLat;
private double sourceLng;
private double destinationLat;
private double destinationLng;
public UsersLocation(){}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int locationId;
#ManyToOne
#JoinColumn(name = "userId")
private User user;
public void setUserId(User user){
this.user = user;
}
public User getUserId(){
return user;
}
#Column(name = "SourceLat", nullable = false)
public double getSourceLat(){
return sourceLat;
}
public void setSourceLat(double sourceLat){
this.sourceLat = sourceLat;
}
#Column(name = "SourceLng", nullable = false)
public double getSourceLng(){
return sourceLng;
}
public void setSourceLng(double sourceLng){
this.sourceLng = sourceLng;
}
#Column(name = "DestinationLat", nullable = false)
public double getDestinationLat(){
return destinationLat;
}
public void setDestinationLat(double destinationLat){
this.destinationLat = destinationLat;
}
#Column(name = "DestinationLng", nullable = false)
public double getDestinationLng(){
return destinationLng;
}
public void setDestinationLng(double destinationLng){
this.destinationLng = destinationLng;
}
}
User Class
#Entity
#Table(name = "users")
public class User implements Serializable{
private static final long serialVersionUID = 1L;
private Integer userId;
private String email;
private String lastName;
private String firstName;
private String location;
public User() {
}
#Id
#Column(name = "userId", unique = true, nullable = false)
public Integer getUserId() {
return this.userId;
}
public Integer setUserId(Integer socialId) {
return this.userId = socialId;
}
#Column(name = "email", nullable = false, length = 50)
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Column(name = "firstName", nullable = true, length = 20)
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#Column(name = "lastName", nullable = true, length = 20)
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Column(name = "location", nullable = true, length = 50)
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
When I save the location I get the userId NULL,I am new to hibernate kindly help me
Thanks
Save the whole user object to the session like below instead of just the userId, as later you need to set the full User object in location.setUserId(user);
WebUtils.setSessionAttribute(request, "userId", user)
If you're saying that you want to save a Location in the database along with the UserId, you have this relation wrong. This should be a OneToOne, since each location will have only one UserId associated.
On the other hand, if you're trying to set a location capable of storing many userIds, you're also doing it wrong because you should be saving a set of users, something like:
#OneToMany(mappedBy = "UsersLocation")
private Set<User> user;
It's not really clear what you're trying to do, but I'm pretty sure your mistake lies in the fact that you're doing the relations in the wrong way.

Categories