问题:
有没有人知道如何合并而不EntityManager
试图重新插入外国实体?
场景:
只是为了设置一个与我的案例非常匹配的场景:我有两个实体
@Entity
@Table(name = "login", catalog = "friends", uniqueConstraints =
@UniqueConstraint(columnNames = "username"))
public class Login implements java.io.Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private Integer id;
@Column(name = "username", unique = true, nullable = false, length = 50)
private String username;
@Column(name = "password", nullable = false, length = 250)
private String password;
}
@Entity
@Table(name = "friendshiptype", catalog = "friends")
public class FriendshipType implements java.io.Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private Integer id;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "username")
private Login login;
@Column(name = "type", unique = true, length = 32)
private String type;
...//other fields go here
}
Run Code Online (Sandbox Code Playgroud)
无论是Login
实体和FriendshipType
实体分别保存到数据库.然后,稍后,我需要将Login
行与FriendshipType
行合并.当我调用时entityManager.merge(friendship)
,它会尝试插入一个新的Login
,当然会导致以下错误
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'myUserName1350319637687' for key 'username'
Error Code: 1062
Call: INSERT INTO friends.login (password, username) VALUES (?, ?)
Run Code Online (Sandbox Code Playgroud)
我的问题是,如何在不让enityManager尝试重新插入外来对象的情况下合并两个对象?
这是我如何解决问题.我终于想出合并没有解决的原因是因为login.id是由JPA自动生成的.因为我真的不需要自动生成的id字段,所以我将其从模式中删除并username
用作@id
字段:
@Entity
@Table(name = "login", catalog = "friends", uniqueConstraints =
@UniqueConstraint(columnNames = "username"))
public class Login implements java.io.Serializable{
private static final long serialVersionUID = 1L;
@Id
@Column(name = "username", unique = true, nullable = false, length = 50)
private String username;
@Column(name = "password", nullable = false, length = 250)
private String password;
}
Run Code Online (Sandbox Code Playgroud)
我发现的另一个解决方案,我没有实现,但可以帮助其他人,他们需要有一个自动生成的id字段.
而不是Login
为合并创建实例,从数据库中获取实例.我的意思是,而不是
Login login = new Login(); login.setUsername(username); login.setPassword(password);
Run Code Online (Sandbox Code Playgroud)
相反
Login login = loginDao.getByUsername(username);
Run Code Online (Sandbox Code Playgroud)
这样,不会生成新的id字段,使实体看起来不同.
感谢并向所有人提供帮助,特别是@mijer非常耐心.
归档时间: |
|
查看次数: |
16020 次 |
最近记录: |