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 User
s 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?
CodePudding user response:
In your User
entity @Id @GeneratedValue
create column with Primary key
but not with Auto Increment
and while you insert data manually inside id
column it produce error, because it is Primary key
...
Change:
@Id @GeneratedValue
To:
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
For auto increment
CodePudding user response:
Try adding this under your @Id annotation
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)