gpt4 book ai didi

java - Spring Boot OneToOne保存(): A different object with the same identifier value was already associated with the session

转载 作者:行者123 更新时间:2023-11-30 02:35:29 28 4
gpt4 key购买 nike

我认为我正在插入 Spring Boot 和 Hibernate 使用的极其简单的情况。我的目的是存储有关 Cyclist 的信息类里面User类(class) OneToOne关系。

注册期间,User的实例类被创建并存储到数据库中。当用户刷新时/home页面,点击计数器增加并保存(更新)实体。这是一个简单的 session 测试和更新数据库,它有效:

@Controller
@SessionAttributes("user")
@RequestMapping("/home")
public class HomeController {
@Autowired private UserSession userSession;
@Autowired private UserDAO userDAO;

@GetMapping
public String home(Model model) {
User user = userSession.getUser();
user.setClicks(user.getClicks() + 1);

userDAO.save(user);

return "home";
}
}

当用户满足 /createCyclist 时就会出现问题形式:

@Autowired private UserDAO userDAO;

@PostMapping
public String createCyclist(@Valid CyclistCreationForm cyclistCreationForm, BindingResult bindingResult, Model model) {
/* Form handling */
User user = userSession.getUser();

Cyclist cyclist = new Cyclist(user, cyclistCreationForm.getHeight(), cyclistCreationForm.getGender());
user.setCyclist(cyclist);

userDAO.save(user);
return "redirect:/home";
}

上面的执行没有异常,但强制用户浏览器加载/home 页面。从这一刻起,调用userDAO.save(user)/home产生异常:

javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session [<package>.Cyclist#1]

其余的异常是无用的堆栈跟踪。

这就是我的设计方式Cyclist类:

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table(name="cyclists")
public class Cyclist {
private int id;
private User user;

/* Some float fields */

@Id
public int getId() {
return id;
}

@MapsId
@OneToOne
@PrimaryKeyJoinColumn
public User getUser() {
return user;
}
}

User类:

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Table(name="users")
public class User implements Serializable {
private Integer uid;
private String name;
private String password;

private Cyclist cyclist;

private int clicks;

@Id
@GeneratedValue
@NotNull
@Column(unique = true)
public Integer getUid() {
return uid;
}

@NotNull
public String getName() {
return name;
}

@NotNull
public String getPassword() {
return password;
}

@OneToOne(cascade = CascadeType.ALL)
public Cyclist getCyclist() {
return cyclist;
}

public int getClicks() {
return clicks;
}
}

我阅读了 SO/google 上发布的许多问题,但无法解决我的问题。

用户和骑行者 DAO 为 CrudRepository实现。我正在使用 lombok 生成样板代码。我对lombok的@Data有点了解如果是 hashCodetoString所以我尝试只使用 @Getter@Setter 。并没有解决问题。

最佳答案

该问题是由 @MapsId 引起的。简单的 @OneToOne 映射仅需要:

用户.java:

@OneToOne(cascade = CascadeType.ALL)
public Cyclist getCyclist() {
return cyclist;
}

Cyclist.java:

@OneToOne
@PrimaryKeyJoinColumn
public User getUser() {
return user;
}

然后,您可以通过对 user 调用 setCyclistuserDao.save(user) 来保存所有内容。

过去,我想让 Cyclist 的主键也成为等于用户 uid 的外键。这不需要 users 表中的附加字段。所以我尝试使用 @MapsId 并忘记它。我将尝试按照本教程描述的方式实现双向共享主键:

http://websystique.com/hibernate/hibernate-one-to-one-bidirectional-with-shared-primary-key-annotation-example/

编辑:我按照我说的做了。 Cyclist主键与User id相同的一对一映射:

用户.java:

@OneToOne(mappedBy="user", cascade = CascadeType.ALL)
public Cyclist getCyclist() {
return cyclist;
}

Cyclist.java:

@Id
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign",parameters=@Parameter(name="property", value="user"))
public int getId() {
return id;
}

@OneToOne
@PrimaryKeyJoinColumn
public User getUser() {
return user;
}

关于java - Spring Boot OneToOne保存(): A different object with the same identifier value was already associated with the session,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43229668/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com