Cascading of persist, does not create identifiaction - spring

Having this entities:
User.java:
#Entity
#NoArgsConstructor
#Getter
#Setter
public class User {
#Id #GeneratedValue
private Long id;
private String username;
#OneToMany(mappedBy = "owner", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#MapKey(name = "friend_id")
private Map<User, Friendship> friends = new HashMap<>();
}
Friendship.java:
#Entity
#Data
#IdClass(Friendship.class)
public class Friendship implements Serializable {
#Id
private Long owner_id;
#Id
private Long friend_id;
private String level;
#ManyToOne(cascade = CascadeType.ALL)
#MapsId("owner_id")
private User owner;
#ManyToOne(cascade = CascadeType.ALL)
#MapsId("friend_id")
private User friend;
}
and DemoApplication.java:
#Bean
public CommandLineRunner loadData(UserRepository userRepo){
return new CommandLineRunner() {
#Override
public void run(String... args) throws Exception {
User owner = new User();
owner.setUsername("owner");
User f1 = new User();
f1.setUsername("f1");
User f2 = new User();
f2.setUsername("f2");
Friendship fs1 = new Friendship();
fs1.setOwner(owner);
fs1.setFriend(f1);
Friendship fs2 = new Friendship();
fs2.setOwner(owner);
fs2.setFriend(f2);
owner.getFriends().put(f1, fs1);
owner.getFriends().put(f2, fs2);
userRepo.saveAndFlush(owner);
}
};
}
I get error:
A different object with the same identifier value was already associated with the session : [com.example.demo.model.Friendship#Friendship(owner_id=null, friend_id=null, level=null, owner=com.example.demo.model.User#2b036135, friend=com.example.demo.model.User#a9e28af9)]
Which means both Users f1 and f2, are having null in Long id. The indeed have, when the object is created, but I thought the mapping had specified CascadeType.ALL and #GeneratedValue so the if should be created.
But I had try to set the ids myself:
...
f1.setUsername("f1");
f1.setId(1L);
User f2 = new User();
f2.setUsername("f2");
f2.setId(2L);
...
But now I got
detached entity passed to persist: com.example.demo.model.User
So I guess I should let the creation of primary keys on JPA. But as you saw from above, it does not that even with Cascading. So what now?

Try adding this under your #Id annotation
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)

Related

JPA OneToOne and shared primary key need manual assignment

I'm using Springboot and JPA to create two tables sharing the same primary key.
For the first table I write:
public class UserAccount implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#OneToOne(mappedBy ="user", cascade = {CascadeType.REMOVE, CascadeType.MERGE,
CascadeType.REFRESH}, fetch=FetchType.LAZY)
#PrimaryKeyJoinColumn
private UserLogin login;
}
For the second table I write:
public class UserLogin implements Serializable
{
#Id
private Long user_id;
#OneToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH},
fetch=FetchType.LAZY)
#MapsId("user_id")
#JoinColumn(name = "user_id", referencedColumnName = "id")
#Setter(AccessLevel.NONE)
private UserAccount user;
public void setUser(UserAccount user)
{
this.user = user;
this.user_id = user.getId();
}
}
Other stuff are omitted for conciseness. The code works because I manually set the id of UserLogin by writing the statement
this.user_id = user.getId();
otherwise I get the error:
Hibernate error: ids for this class must be manually assigned before calling save():
I guess that the ids can be manually managed but I cannot get the right configuration.
UPDATE:
I found the solution thanks (see the accepted answer). Now I just would get rid of the findById() when setting the user login.
//these methods are defined within a dedicated #Service
#Transactional
public void createLoginInfo(UserAccount user)
{
UserLogin userlogin=new UserLogin();
this.addLoginToUser(userlogin,user);
loginService.save(userlogin);
}
#Transactional
public void addLoginToUser(UserLogin login, UserAccount account)
{
//whit this commented line works
//UserAccount acc= this.findById(account.getId());
login.setUser(account);
account.setLogin(login);
}
//In a transactional test method I first create the user then I call
userService.save(theuser);
userService.createLoginInfo(theuser);
You have a bidirectional relationship, but have mapped it with a few competing options that don't work well together. First, in UserAccount, it isn't clear why you have an ID that is generated, yet try to also map it with the relationship (specifically using a PrimaryKeyJoinColumn). If you want it generated, it can't also be a foreign key value in a reference - and you've already got this relationship setup as the 'other' side via the 'mappedBy' setting. It should just be:
public class UserAccount implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#OneToOne(mappedBy ="user", cascade = {CascadeType.REMOVE, CascadeType.MERGE,
CascadeType.REFRESH}, fetch=FetchType.LAZY)
private UserLogin login;
}
User login then should just be:
public class UserLogin implements Serializable {
#Id
private Long user_id;
#OneToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH},
fetch=FetchType.LAZY)
#MapsId("user_id")
#JoinColumn(name = "user_id", referencedColumnName = "id")
#Setter(AccessLevel.NONE)
private UserAccount user;
public void setUser(UserAccount user) {
this.user = user;
}
}
Note because you have the mapsId annotation on the user relationship, JPA will set the user_id property for you once the ID is assigned - there is no need to manually set it yourself. You can, but if you do you must insure it was assigned previously - which requires a save/flush on the UserAccount. If you don't actually use the Long user_id property, you don't really even need to map it; you can just mark the user property as the ID:
public class UserLogin implements Serializable {
#Id
#OneToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH},
fetch=FetchType.LAZY)
#JoinColumn(name = "user_id", referencedColumnName = "id")
#Setter(AccessLevel.NONE)
private UserAccount user;
public void setUser(UserAccount user) {
this.user = user;
}
}
The Long ID from UserAccount then can be used to lookup UesrAccounts and UserLogin instances.
Try this :
public class UserLogin implements Serializable
{
#Id
private Long user_id;
#OneToOne(fetch=FetchType.LAZY)
#MapsId
#JoinColumn(name = "user_id")
private UserAccount user;
public UserAccount getUser() {
return user;
}
public void setUser(UserAccount user) {
this.user = user;
}
}
public class UserAccount implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
}
To persist UserLogin :
EntityManager em;
UserAccount user = em.find(UserAccount.class, 1L)
UserLogin login = new UserLogin();
login.setUser(user);
em.persist(login);

Spring JPA Unable To Find Composite Foreign Key Target Column (Non-PK)

User.java
#Entity
#Table(name = "users")
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "user_role_id", referencedColumnName = "id")
private UserRole userRole;
}
UserRole.java
#Data
#Entity
#Table(name = "user_roles")
public class UserRole implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
}
Client.java
#Data
#Entity
#Table(name = "clients")
public class Client implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumns({ #JoinColumn(name = "user_id", referencedColumnName = "id"),
#JoinColumn(name = "user_role_id", referencedColumnName = "user_role_id") })
private User user;
}
Error
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.MappingException: Unable to find column with logical name: user_role_id in users
In RDBMS, users.(id, user_role_id) is unique so clients table can refer to that.
Last time, I was using insertable = false, updatable = false on user_role_id, but when I want to add records of new client, I always need to add user_role_id manually user.setUserRoleId(userRole.getId()) after user.setUserRole(userRole) and I think that is bad practice of ORM (it should be added automatically when I set user.setUserRole(userRole))
#Column(name = "user_role_id", insertable = false, updatable = false)
private Integer userRoleId;
What should I do so the relation can be mapped in Spring JPA? and what is the best practice?
In other words, this is also mean how to reference to foreign key generated logical name column?
OK! Please try following configuration:
Below is a important code part and under this link you may find repository with working example
UserRole.java
#Data
#Entity
#Table(name = "user_roles")
public class UserRole implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "role_id")
private Integer roleId;
}
User.java
#Data
#Entity
#Table(name = "users")
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "user_id")
private Integer userId;
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "user_role_id", referencedColumnName = "role_id")
private UserRole userRole;
}
Client.java
#Data
#Entity
#Table(name = "clients")
public class Client implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "client_id")
private Integer clientId;
#OneToOne(fetch = FetchType.LAZY)
#JoinColumns(
value = {
#JoinColumn(name = "client_role_id", referencedColumnName = "user_role_id"),
#JoinColumn(name = "client_user_id", referencedColumnName = "user_id"),
}
,
foreignKey = #ForeignKey(
name = "FK_user_with_role",
foreignKeyDefinition = "FOREIGN KEY (client_user_id, client_role_id)\n" +
" REFERENCES users \n" +
" (user_id, user_role_id) \n" +
" ON UPDATE CASCADE\n" +
" ON DELETE CASCADE")
)
private User user;
}
Please note that beside adding a foreignKey in the Client implementation, you MUST keep the sequence of #JoinColum annotations.. I don't know what is the reason behind, but if you flip those lines you'll still get your error as it was before :)
EDIT: I've added another answer which fits best in my opinion. I'm leaving this one as well to see the other steps I tried.
Though the solution is not elegant and not using JPA as requested. Just in case anything in here would be helpful
If I understand the main issue correctly - you want to bind Client entity with Role entity via User entity, by first setting User's Role and then transfer that "property" by using only UserId instead setting additionally RoleId while creating Client.
Basically after playing for a while with your model I think the main issue is to assign data to each other within a #Transactional methods. That seems to be caused ba Lazy fetch strategy.
My proposal for solution that binds all your Entities according expectations differs only from yours with ommiting the RoleId JoinColumn in Clients table. I have checked that when calling a service that would have #Transactional methods, you can assign a Role to the User and User to the Client with simple user.setRole(roleEntity) followed by client.setUser(userEntity).
All the data is then consistent. No need to call further like getters and setters as you mentioned in the second part of your question. Question is if for any reason you need to have RoleId as well in your Clients Table, then this soultion would have to be enhanced by additional column?
UserRole.java
#Entity
#Table(name = "user_roles")
public class UserRole implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "role_id")
private Integer roleId;
//getters and setters and toString
}
User.java
#Entity
#Table(name = "users")
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "user_id")
private Integer userId;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "user_role_id", referencedColumnName = "role_id")
private UserRole userRole;;
//getters and setters and toString;
}
Client.java
#Entity
#Table(name = "clients")
public class Client implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "client_id")
private Integer clientId;
#OneToOne(fetch = FetchType.LAZY)
#JoinColumns({
#JoinColumn(name = "client_user_id", referencedColumnName = "user_id"),
})
private User user;
#Column(name = "client_role_id")
private Integer roleId;
#PrePersist
#PreUpdate
private void prePersist(){
try {
roleId = getUser().getUserRole().getRoleId();
} catch (NullPointerException e){
roleId = null;
}
}
//getters and setters and toString
}
UserService.java
#Service
public class UserService {
UserRepo userRepo;
public UserService(UserRepo userRepo) {
this.userRepo = userRepo;
}
#Transactional
public void save(User user) {
userRepo.save(user);
}
#Transactional
public User getReferenceById(int i) {
return userRepo.getReferenceById(i);
}
}
ClientService.java
#Service
public class ClientService {
private ClientRepo clientRepo;
private UserService userService;
public ClientService(ClientRepo clientRepo, UserService userService) {
this.clientRepo = clientRepo;
this.userService = userService;
}
#Transactional
public Client save(Client client){
return clientRepo.save(client);
}
#Transactional
public Client getReferenceById(int i) {
return clientRepo.getReferenceById(i);
}
#Transactional
public void printClient(Client client){
client = clientRepo.getReferenceById(client.getClientId());
System.out.println(client);
}
#Transactional
public void bindUserToClient(int userId, int clientId) {
Client entity = clientRepo.findById(clientId).orElseGet(Client::new);
entity.setUser(userService.getReferenceById(userId));
}
#Transactional
public void printClient(int i) {
clientRepo.findById(i).ifPresentOrElse(this::printClient, EntityNotFoundException::new);
}
}
This configuration after running this commandLineRunner:
#Configuration
public class Config {
#Bean
#Transactional
public CommandLineRunner commandLineRunner(
#Autowired UserRoleRepo roleRepo,
#Autowired UserService userService,
#Autowired ClientService clientService
) {
return args -> {
for (int i = 0; i < 5; i++) {
roleRepo.save(new UserRole());
}
for (int i = 5; i > 0; i--) {
User user = new User();
user.setUserRole(roleRepo.getReferenceById(i));
userService.save(user);
}
Client client = new Client();
client.setUser(userService.getReferenceById(2));
client = clientService.save(client);
clientService.printClient(client);
client = new Client();
client.setClientId(1);
clientService.printClient(client);
int userId = 5;
clientService.bindUserToClient(userId, 1);
clientService.printClient(1);
};
}
}
gave me correct output in the console:
Client{id=1, user=User{id=2, userRole=UserRole{id=4}}}
Client{id=1, user=User{id=2, userRole=UserRole{id=4}}}
Client{id=1, user=User{id=5, userRole=UserRole{id=1}}}
WORKAROUND
I tried to reach the goal by use of Spring JPA but could'nt.
The workaround that keeps the referential integrity was by creating a constrains through DB like below and add #PrePersist and #PreUpdate annotated method which is updating the client's roleId as intended.
create table clients
(
client_id integer not null,
client_user_id integer,
client_role_id integer,
primary key (client_id)
);
create table user_roles
(
role_id integer generated by default as identity,
primary key (role_id)
);
create table users
(
user_id integer generated by default as identity,
user_role_id integer,
primary key (user_id),
CONSTRAINT User_Role UNIQUE (user_id, user_role_id)
);
alter table users
add constraint FK_role_id foreign key (user_role_id) references user_roles (role_id);
alter table clients
add constraint FK_user_id foreign key (client_user_id, client_role_id) references users (user_id, user_role_id) on update cascade ;
Thanks to that I could for instance update userRole in user entity, and the change was reflected in the clients table as well without any further actions

Mapping DTO to existing entity , it is creating new entity

I have Activity class and ActivityDTO as you see below. While saving new entity there is no problem, but if I want to update existing entity, then it is creating new entity although my entity id is from my database entity.
#Getter
#Setter
#Entity
public class Activity implements Serializable {
#Id
#Column(name = "ID")
#GeneratedValue
#SequenceGenerator
private Long id;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval=true)
#JoinTable(name = "ACTIVITY_ATTACHMENT", joinColumns = {
#JoinColumn(name = "ACTIVITY_ID") }, inverseJoinColumns = { #JoinColumn(name = "ATTACHMENT_ID") })
private Set<Attachment> attachments = new HashSet<>();
#Temporal(TemporalType.DATE)
#JsonSerialize(using = CustomJsonDateSerializer.class)
#JsonDeserialize(using = CustomJsonDateDeserializer.class)
#Column(name = "BEGIN_DATE")
private Date beginDate;
#Temporal(TemporalType.DATE)
#JsonSerialize(using = CustomJsonDateSerializer.class)
#JsonDeserialize(using = CustomJsonDateDeserializer.class)
#Column(name = "END_DATE")
private Date endDate;}
And my ActivityDTO
#Getter
#Setter
public class ActivityDTO {
private Long id;
private Set<Attachment> attachments = new HashSet<>();
#Temporal(TemporalType.DATE)
#JsonSerialize(using = CustomJsonDateSerializer.class)
#JsonDeserialize(using = CustomJsonDateDeserializer.class)
private Date beginDate;
#Temporal(TemporalType.DATE)
#JsonSerialize(using = CustomJsonDateSerializer.class)
#JsonDeserialize(using = CustomJsonDateDeserializer.class)
private Date endDate;
And here is my ActivityController class;
public Activity save(ActivityDTO activityDTO, List<MultipartFile> fileList) throws Exception {
Activity activity = convertActivityDTOtoEntity(activityDTO);
activity.getAttachments().addAll(ObjectFactory.createAttachment(fileList, Activity.class));
return activityRepository.save(activity);
}
public Activity update(ActivityDTO activityDTO, List<MultipartFile> fileList) throws Exception {
Activity activity = convertActivityDTOtoEntity(activityDTO);
activity.getAttachments().addAll(ObjectFactory.createAttachment(fileList, Activity.class));
return activityRepository.save(activity);
}
private Activity convertActivityDTOtoEntity(ActivityDTO activityDTO) {
return modelMapper.map(activityDTO, Activity.class);
}
Also I have one more problem, I have just transformed my entity usage to DTO objects, until now service was reaching entity directly and while updating if I delete any attachment or add, there was no problem. After I transformed to DTO objects and used like above, there is a problem while updating;
detached entity passed to persist: com.thy.agencycrm.entity.Attachment
And here is my Attachment entity if you would like to see;
#Getter
#Setter
#Entity
public class Attachment implements Serializable {
#Id
#Column(name = "ID")
#GeneratedValue
#SequenceGenerator
private Long id;
#Column(name = "MIME_TYPE")
private String mimeType;
Please help me about this problem, I am searhing and trying to solve it for long times.
Thanks you in advance.
I think you just copy the fields into a new object in your converter right?
Default JPA only update the entity if it is in the persistance context and the two object are identical. If you have a detached object, create a new one with in the converter, it will be saved as new record. It does not matter if you set the ID, because the id is generated by the sequence, as you annotated on the entity class.
You can resolve this many ways. The easiest is to load the entity by id, and set the fields from the another object into this managed object.
Updated your Class ActivityController
public Activity save(ActivityDTO activityDTO, List<MultipartFile> fileList) throws Exception {
Activity activity = convertActivityDTOtoEntity(activityDTO);
activity.getAttachments().addAll(ObjectFactory.createAttachment(fileList, Activity.class));
return activityRepository.save(activity);
}
public Activity update(ActivityDTO activityDTO, List<MultipartFile> fileList) throws Exception {
Activity activity = activitiyRepository.findOne(activityDTO.getID());
// This will update the existing activity with activityDTO
modelMapper.map(activityDTO, activity);
activity.getAttachments().addAll(ObjectFactory.createAttachment(fileList, Activity.class));
return activityRepository.save(activity);
}
private Activity convertActivityDTOtoEntity(ActivityDTO activityDTO) {
return modelMapper.map(activityDTO, Activity.class);
}

Why I can't delete data in cascade way?

The problem is when I want to delete user I'm getting error in Spring Boot like that:
java.sql.SQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (32506632_pam.badge, CONSTRAINT FK4aamfo6o0h5ejqjn40fv40jdw FOREIGN KEY (user_id) REFERENCES user (id))
I'm guessing that I need to delete data in cascade way. So I've placed CascadeType.REMOVE value to #OneToOne annotation like that, but it doesn't work:
badge entity
#Entity
#Data
#Table(name = "badge")
#AllArgsConstructor
#NoArgsConstructor
public class Badge {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#JsonManagedReference
#ManyToMany(mappedBy = "badges", fetch = FetchType.LAZY)
private List<Reader> readers;
#OneToOne(cascade = CascadeType.REMOVE, orphanRemoval=true)
#JoinColumn(name = "user_id")
private User user;
private String number;
#Lob
#Basic(fetch = FetchType.LAZY)
private byte[] photo;
}
user entity
#Entity
#Data
#Table(name = "user")
#AllArgsConstructor
#NoArgsConstructor
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String lastname;
private String pesel;
private String email;
private String telephone;
private Integer age;
private String gender;
}
reader entity
#Entity
#Data
#Table(name = "reader")
#AllArgsConstructor
#NoArgsConstructor
public class Reader {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#JsonBackReference
#ManyToMany(fetch = FetchType.LAZY)
private List<Badge> badges;
private String department;
private String room;
private Boolean status;
}
Class which loads initial data
#Component
public class DataLoader implements ApplicationRunner {
#Autowired
private UserService userService;
#Autowired
private BadgeService badgeService;
#Autowired
private ReaderService readerService;
#Override
public void run(ApplicationArguments args) throws Exception {
User user1 = new User(null, "Jan", "Kowal", "11111111111", "jan#kowal.pl", "+48111111111", new Integer(23), "male");
userService.saveUser(user1);
Reader reader1 = new Reader(null, null, "Warehouse", "207A", new Boolean("true"));
Badge badge1 = new Badge(null, Arrays.asList(reader1), user1, "738604289120", null);
badgeService.saveBadge(badge1);
reader1.setBadges(Arrays.asList(badge1));
readerService.saveReader(reader1);
}
}
Endpoint for deleting user - it uses repository which extends CrudRepository and uses default delete behavior.
#DeleteMapping("/deleteUserById/{id}")
private void deleteUserById(#PathVariable Long id) {
userService.deleteUserById(id);
}
Database structure in phpmyadmin
My goal is to delete user and associated badge with him, then to delete row in reader_badges table.

Spring boot JPA many to many with extra column insert and update issue

Here is my initial question.
Spring Data JPA Many to Many with extra column User and Roles
Now I have the right tables created, but can't make it work for the update.
Here is the code:
User.java
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
#OneToMany(mappedBy="user", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private List<UserRole> roles;
// getters and setters
}
Role.java
#Entity
#Table(name = "roles")
public class Role {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// getters and setters
}
UserRole.java
#Entity
#Table(name = "users_to_role")
public class UserRole implements Serializable {
#Id
#ManyToOne
#JoinColumn(name = "user_id")
private User user;
#Id
#ManyToOne
#JoinColumn(name = "role_id")
private Role role;
private Date createdAt;
public UserRole(){}
public UserRole(User user, Role role, Date date) {
this.user = user;
this.role = role;
this.createdAt = date;
}
// getters and setters
}
Controller
#RestController
public class APIController {
#Autowired
RoleRepository roleRepository;
#Autowired
UserRepository userRepository;
#ResponseBody
#RequestMapping(value = "create", method = RequestMethod.GET)
public String create(){
//Insert test - WORKING BUT NOT SURE IF ITS RIGHT WAY
List<UserRole> userRoles = new ArrayList<>();
Role role = roleRepository.getOne((long) 1);
//Create user
User user = new User();
user.setUsername("test");
//Create userRole
userRoles.add(new UserRole(user, role, new Date()));
user.setRoles(userRoles);
userRepository.save(user);
return "created";
}
#ResponseBody
#RequestMapping(value = "edit", method = RequestMethod.GET)
public String edit(){
//Edit test - NOT working
List<UserRole> userRoles = new ArrayList<>();
Role role = roleRepository.getOne((long) 2);
//get user from db
User user = userRepository.getOne((long) 1);
//Create userRole
userRoles.add(new UserRole(user, role, new Date()));
// WAS FIRST ATTEMPT using user.setRoles(userRoles); but got error and use
//https://stackoverflow.com/questions/9430640/a-collection-with-cascade-all-delete-orphan-was-no-longer-referenced-by-the-ow
//user.setRoles(userRoles);
user.getRoles().clear();
user.getRoles().addAll(userRoles);
userRepository.save(user);
return "done";
}
}
I am getting this error:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'user_id' cannot be null

Resources