【问题标题】:Cascading of persist, does not create identifiaction级联持久化,不创建标识
【发布时间】:2021-11-10 09:08:40
【问题描述】:

拥有这个实体:

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;
}

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);
            }
        };
    }

我得到错误:

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)]

这意味着Users f1f2Long id 中都具有空值。确实有,当创建对象时,但我认为映射指定了CascadeType.ALL@GeneratedValue 所以应该创建if。

但我曾尝试自己设置 ID:

            ...
            f1.setUsername("f1");
            f1.setId(1L);
            User f2 = new User();
            f2.setUsername("f2");
            f2.setId(2L);
            ...

但现在我得到了

detached entity passed to persist: com.example.demo.model.User

所以我想我应该让在 JPA 上创建主键。但正如您从上面看到的那样,即使使用 Cascading 也不是这样。那么现在呢?

【问题讨论】:

    标签: spring hibernate jpa orm


    【解决方案1】:

    尝试在 @Id 注释下添加它

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    

    【讨论】:

    • strategy=GenerationType.AUTO 不创建具有自动增量的列试试...
    • 它是用来生成id值的,我从来没有说过它创建一个列。
    • 那么,为什么要从答案中删除strategy=GenerationType.AUTO
    • 还是同样的错误A different object with the same identifier value was already associated with the session
    【解决方案2】:

    在您的User 实体@Id @GeneratedValue 中使用Primary key 而不是Auto Increment 创建列,当您在id 列中手动插入数据时,它会产生错误,因为它是Primary key...

    变化:

    @Id @GeneratedValue
    

    收件人:

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    

    自动递增

    【讨论】:

    猜你喜欢
    • 2018-05-15
    • 2011-03-12
    • 1970-01-01
    • 2020-02-13
    • 2016-10-04
    • 2019-10-20
    • 2015-11-02
    • 2013-08-24
    • 2018-01-02
    相关资源
    最近更新 更多