#ManyToMany values are always null - java

I have this POJO class:
package com.weather.weather.entity;
import jakarta.persistence.*;import lombok.Data;
import lombok.NoArgsConstructor;import org.hibernate.annotations.Proxy;import org.springframework.transaction.annotation.Transactional;
import java.util.List;import java.util.Set;
#Entity#Table(name = "users")#Data#NoArgsConstructor
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "username")
private String username;
#Column(name = "password")
private String password;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "collaborator",
joinColumns = #JoinColumn(name = "user_id"),
inverseJoinColumns = #JoinColumn(name = "role_id")
)
private Set<Role> roles;
}
Also Role class:
package com.weather.weather.entity;
import jakarta.persistence.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Proxy;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Set;
#Entity
#Table(name = "roles")
#Data
#NoArgsConstructor
public class Role {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// #OneToMany(mappedBy = "role")
// private List<User> users;
#ManyToMany(mappedBy = "roles")
private Set<User> users;
}
But always getRoles() are null.
I have tried changing data to #OneToOne, #ManyToOne, #OneToMany.But its always null.At some point, when i was doing #ManyToOne way, i have got this exception:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.weather.weather.entity.Role.users: could not initialize proxy - no Session
And i found to ways to fix that. I`ve tried putting fetch property, #Proxy(lazy=false), and many many others. Nothing helped

Your annotation #ManyToMany imported from jakarta.persistence.
You should import from javax.persistence.* and you can remove proxy annotation and Lazy fetchType

Related

How can I auto create the associative (or junction) table in many-to-many relationship using JPA Buddy

I am using the JPA Buddy plugin in IntelliJ, and I want to quickly create sql script (MySQL) from the entity class of Student and Course (many-to-many relationship).
I have successfully created the course and student table, but look like JPA Buddy does not have the option to create the associative (junction) table "student_course" (as showed in picture below)? Can JPA Buddy create the associative (junction) table in many-to-many relationship?
Student and Course class for code references:
Student.java
#Table(name = "student")
#Entity
#Getter
#Setter
public class Student {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false)
private Long id;
#Column(name = "name")
private String name;
#ManyToMany
#JoinTable(name = "student_course",
joinColumns = #JoinColumn(name = "student_id"),
inverseJoinColumns = #JoinColumn(name = "courses_id"))
private Set<Course> courses;
}
Course.java
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.util.Set;
#Table(name = "course")
#Entity
#Getter
#Setter
public class Course {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false)
private Long id;
#Column(name = "name")
private String name;
#ManyToMany(mappedBy = "courses")
private Set<Student> students;
}
Thanks for reporting! JPAB-1448 и JPAB-1469 tickets were closed and it works since the 2022.1.0 version of JPA Buddy

Why Doesn't jpa add data to the foreign key value

I have a users table which contains the user details. i also have a authorities table which has the role of a user. The user and authorities table has one to many mapping. When i try to save the details using Jpa the foreign key column is blank no data is inserted in that field. i have a form in which i am specifying the role of the user along with other details.
package com.example.StarsProject.Model;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
#Entity
#Table
#Getter
#Setter
public class Authorities {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String role;
#ManyToOne(cascade = CascadeType.PERSIST,fetch=FetchType.EAGER)
#JoinColumn(name = "users_id", referencedColumnName = "id")
private Users users;
public Authorities(String role){
this.role = role;
}
}
package com.example.StarsProject.Model;
import com.example.StarsProject.DTO.UserDTO;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
#Entity
#Table
#Getter
#Setter
public class Users {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(name = "first_name")
private String firstname;
#Column(name = "last_name")
private String lastname;
#Column(unique = true)
private String email;
private String password;
#OneToMany(fetch = FetchType.EAGER,targetEntity = Authorities.class,mappedBy = "users", cascade = CascadeType.PERSIST)
private Set<Authorities> authorities;
public Users(UserDTO userDTO) {
this.email = userDTO.getEmail();
this.firstname = userDTO.getFirstname();
this.lastname = userDTO.getLastname();
this.password = userDTO.getPassword();
// Authorities authorities = new Authorities();
// authorities.setRole(userDTO.getRole());
// Set<Authorities> set = new HashSet<>();
// set.add(authorities);
this.authorities = new HashSet<Authorities>(Arrays.asList(new Authorities(userDTO.getRole())));
}
}
package com.example.StarsProject.Service;
import com.example.StarsProject.DTO.UserDTO;
import com.example.StarsProject.Model.Users;
import com.example.StarsProject.Repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class UserDetailsServiceImpl implements UserDetailsServiceInterface{
#Autowired
UserRepository userRepository;
#Override
public void storeUserDetails(UserDTO userDTO) {
Users users = new Users(userDTO);
userRepository.save(users);
}
}
When i try to save the user details it doesn't insert any value in the foreign key column. Can someone tell me what i am doing wrong.
You need to setusers field in Authorities manually. Hibernate won't fill it for you.

Whole table not showing in JSON when doing Hibernate mapping

The table is created successfully and filled with information in H2 database as seen here:
When using Spring boot to display this table information with JSON format i only see this:
Here you can see the code snippet from the object
package com.share.sharelt.entity;
import com.fasterxml.jackson.annotation.JsonBackReference;
import lombok.Data;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;
#Entity
#Data
#Table(name = "item_rental")
public class ItemRental {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private long id;
#Column(name = "created")
private Date created;
#Column(name = "cost")
BigDecimal cost;
#Column(name = "rent_begin")
private Date rentBegin;
#Column(name = "rent_end")
private Date rentEnd;
#Column(name = "is_confirmed")
private boolean isConfirmed;
#JsonBackReference
#OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "renter_id", nullable = true)
private User user;
public ItemRental(){};
}
The problem is that i want to see the whole table information, more specifically the "renter_id" column
One of the solutions is to create a DTO class which is gonna be a JSON wrapper to your ItemRental entity
Something like ItemRentalDTO and UserDTO with all fields of ItemRental and User entity class
Link: https://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application

What is the correct way to include a Map<Entity, Entity> field

I've got an entity class MyEntity that can be associated with other MyEntitys. I want to define the relationship between the MyEntitys. So I've ended up with a class like
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Accessors;
import javax.persistence.*;
import java.util.HashMap;
import java.util.Map;
#Data
#NoArgsConstructor
#RequiredArgsConstructor
#Accessors(chain = true)
#Entity
#Table
public class MyEntity {
#Id
#GeneratedValue
private Long id;
#NonNull
private String name;
private String email;
private String phone;
#NonNull
#OneToOne
private MyEntityType myEntityType;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private Map<String, Address> addresses = new HashMap<>();
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable()
private Map<Relationship, MyEntity> relationships = new HashMap<>();
public MyEntity addAddress(String key, Address address) {
addresses.put(key, address);
return this;
}
public MyEntity addRelationship(Relationship relationship, MyEntity myEntity) {
relationships.put(relationship, myEntity);
return this;
}
}
Where the relationship class looks like
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Accessors;
import javax.persistence.*;
#Data
#NoArgsConstructor
#RequiredArgsConstructor
#Entity
#Table
#Accessors(chain = true)
public class Relationship {
#Id
#GeneratedValue
private Long id;
#NonNull
private String name;
#NonNull
private String antonym;
}
The field in question is the relationships field in MyEntity.
Things seem to work until I delete a MyEntity. If the deleted MyEntity has no relationships everything is ok. If the deleted MyEntity has relationships then the MyEntitys it is related to are also deleted.
If I modify the #ManyToMany annotation to
#ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE})
Then the related MyEntitys are no longer deleted. Does this look like the correct way to do this?
In order to correctly define the Map<Entity, Entity> mapping you need to combine #ManyToMany (or #OneToMany), #JoinTable and the #MapJoinColumn annotations:
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(...)
#MapKeyJoinColumn(name = "relationship_id")
private Map<Relationship, MyEntity> relationships = new HashMap<>();
See here for more examples.

ManyToMany mapping issue in Spring Boot

I'm trying to do a many-to-many mapping between 2 tables users and products. I wrote their entities and repositories but still the application is giving error. Please help me out if you can, thanks in advance.
Error
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.poc.joins.entities.User.users in com.poc.joins.entities.Product.users
The code snippets are
User
package com.poc.joins.entities;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
#Entity
#Table(name = "users")
public class User {
#Id
private String username;
private String password;
#ManyToMany(cascade = CascadeType.MERGE)
#JoinTable(name = "users_products",
joinColumns = {#JoinColumn(name = "username")},
inverseJoinColumns = {#JoinColumn(name = "id")})
private Set<Product> products = new HashSet<>();
}
// Getter, setters, constructors are not shown here
Product
package com.poc.joins.entities;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
#Entity
#Table(name = "products")
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String p_name;
private Integer quantity;
private Float price;
private Float total;
#ManyToMany(mappedBy = "users")
private Set<User> users = new HashSet< >();
}
// Getter, setters, constructors are not shown here
In the owned entity (Product), you pass in the field that owns the relationship (in the User entity):
#ManyToMany(mappedBy = "products")
private Set<User> users = new HashSet< >();
Originally you told the Persistence provider to look for the field called users in the User entity which would hold all the information about the relationship (#JoinTable etc.)

Categories