我有下面的实体类。当用户首次注册时,仅提供用户名和密码,因此帐户列表(思考配置文件)为空。稍后,当他们添加帐户时,会在客户端更新用户对象,传递给服务器,然后调用entityManager.merge(user)。合并用户时,会将帐户添加6次到数据库,并将提供的地址添加三次。我不知道为什么。我想要添加一次帐户,只添加一个地址。关于可能发生的事情的任何想法?
@Entity
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private int id;
@OneToMany(cascade=CascadeType.ALL)
@JoinTable(name="user_accounts")
private List<Account> accounts;
//...getters and setters ...
}
@Entity
public class Account implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private long id;
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="address")
private Address address;
//...getters and setters...
}
@Entity
public class Address implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private int id;
@Column(name="street")
private String street;
@Column(name="city")
private String city;
@Column(name="state")
private String state;
@Column(name="zip")
private String zip;
//...getters and setters...
}
答案 0 :(得分:1)
这是使用合并的已知问题,其中集合是列表。不幸的是现在真正修复了:HHH-5855
答案 1 :(得分:0)
您是否尝试过:
persist(address)
account.setAddress(address)
persist(account)
user.setAccount(account)
merge(user)
我认为因为地址和帐户已经生成了ID,并且您指定了级联导致此问题。
答案 2 :(得分:0)
我对此问题的解决方案是向控制器添加一个额外的函数,该函数将使用本机SQL语句更新行。由于我的代码更新了部分或密钥(长篇故事,但令人惊讶地工作得非常好),我必须确保我没有根据pojo中的新值查找记录。这是代码:
public void editSQLUpdate(Reportinfo reportinfo) throws NonexistentEntityException, Exception {
EntityManager em = null;
try {
em = getEntityManager();
em.getTransaction().begin();
String qry = "UPDATE `boeaudit`.`reportinfo` "
+ "SET "
+ "`author` = '" + reportinfo.getAuthor() + "',"
+ "`db_account` = '" + reportinfo.getDbAccount() + "',"
+ "`db_schema_name` = '" + reportinfo.getDbSchemaName() + "',"
+ "`descriptions` = '" + reportinfo.getDescriptions() + "',"
+ "`DLL` = '" + reportinfo.getDll() + "',"
+ "`parent_folder` = " + reportinfo.getParentFolder() + ","
+ "`path` = '" + reportinfo.getPath() + "',"
+ "`report_title` = '" + reportinfo.getReportTitle() + "',"
+ "`report_id` = " + reportinfo.getReportinfoPK().getReportId() + ","
+ "`env` = " + reportinfo.getReportinfoPK().getEnv() + ","
+ "`db_server` = '" + reportinfo.getReportinfoPK().getDbServer() + "',"
+ "`seq` = " + reportinfo.getReportinfoPK().getSeq()
+ " WHERE `report_id` = " + reportinfo.getReportinfoPK().getReportId()
+ " AND `env` = " + reportinfo.getReportinfoPK().getEnv()
+ " AND `db_server` = '-'" //this is the initial value of the record and the update value differs, so if we pass the new value the record will not be found. ;)
+ " AND `seq` = "+ reportinfo.getReportinfoPK().getSeq();
Query nq = em.createNativeQuery(qry);
int outcome = nq.executeUpdate(); //not doing anything with outcome, but should be used to determine the result of the operation...
em.getTransaction().commit();
} catch (Exception ex) {
String msg = ex.getLocalizedMessage();
if (msg == null || msg.length() == 0) {
ReportinfoPK id = reportinfo.getReportinfoPK();
if (findReportinfo(id) == null) {
throw new NonexistentEntityException("The reportinfo with id " + id + " no longer exists.");
}
}
throw ex;
} finally {
if (em != null) {
em.close();
}
}
}