2009-12-18 18 views
5

Tôi có các lớp thực thể bên dưới. Khi người dùng đăng ký lần đầu, chỉ có tên người dùng và mật khẩu được cung cấp, vì vậy danh sách tài khoản (các tiểu sử suy nghĩ) trống. Sau đó, khi họ thêm một tài khoản, đối tượng người dùng được cập nhật trong máy khách, được chuyển đến máy chủ, và sau đó entityManager.merge (người dùng) được gọi. Khi người dùng được hợp nhất, tài khoản sẽ được thêm 6 lần vào cơ sở dữ liệu và địa chỉ được cung cấp sẽ được thêm ba lần. Tôi cung không chăc tại sao. Tôi muốn tài khoản được thêm một lần và chỉ thêm một địa chỉ. Bất kỳ ý tưởng về những gì có thể xảy ra?Hợp nhất JPA đang gây ra các bản sao

@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

Bạn có thể thả những thứ như @column (name = "id") hoặc @column (name = "zip") nếu bạn không thay đổi tên. – whiskeysierra

+0

máy chủ trực tiếp mặc định là tất cả các tên bảng và cột và máy chủ thử nghiệm của tôi mặc định là chữ thường, vì vậy nó dường như dễ dàng hơn thay đổi cài đặt. – chris

+0

Bạn đã tìm được giải pháp chưa? –

Trả lời

0

Bạn đã cố gắng:

persist(address) 
account.setAddress(address) 
persist(account) 
user.setAccount(account) 
merge(user) 

Tôi nghĩ rằng vì địa chỉtài khoản đã tạo id và bạn chỉ định thác gây ra vấn đề này.

1

Đây là vấn đề đã biết khi sử dụng hợp nhất nơi tập hợp là danh sách. Rất tiếc, hiện tại, khắc phục sự cố thực sự: HHH-5855

+0

Đã sửa trong phiên bản 5.0.8 – aorticDefiance

0

Giải pháp của tôi cho vấn đề này là thêm chức năng bổ sung vào bộ điều khiển sẽ cập nhật hàng bằng câu lệnh SQL gốc. Kể từ khi mã của tôi cập nhật một phần hoặc chìa khóa (câu chuyện dài, nhưng đáng ngạc nhiên làm việc đáng kinh ngạc tốt) Tôi đã phải chắc chắn rằng tôi đã không tìm kiếm hồ sơ dựa trên các giá trị mới trong pojo. đây là đoạn code:

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(); 
     } 
    } 
} 
Các vấn đề liên quan