2014-12-27 10 views
9

Tôi nhận được lỗi này khi nộp mẫu đơn:thực thể tách rời thông qua để tồn tại lỗi

org.hibernate.PersistentObjectException: thực thể tách ra thông qua để tồn tại: com.project.pmet.model.Account; lồng nhau ngoại lệ là javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: thực thể tách ra thông qua để tồn tại: com.project.pmet.model.Account

Dưới đây là các đơn vị của tôi:

tài khoản:

@Entity 
@DynamicInsert 
@DynamicUpdate 
public class Account { 

    @Id 
    @GeneratedValue 
    private Integer id; 

    @Column(nullable = false) 
    private String login; 

    @Column(nullable = false) 
    private String password; 

    @Column(nullable = false) 
    private String email; 

    @ManyToOne 
    @JoinColumn(name = "team_id") 
    private Team team; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner") 
    private List<Team> ownedTeams; 

    ... 

Đội bóng:

@Entity 
@DynamicInsert 
@DynamicUpdate 
public class Team { 

    @Id 
    @GeneratedValue 
    private Integer id; 

    @Column(nullable = false) 
    private String name; 

    @ManyToOne 
    @JoinColumn(name = "owner_id", nullable = false) 
    private Account owner; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "team") 
    private List<Account> members; 

    ... 

Dưới đây là một phần của điều khiển:

@ModelAttribute("team") 
    public Team createTeamObject() { 
     return new Team(); 
    } 

    @RequestMapping(value = "/teams/create-team", method = RequestMethod.GET) 
    public String getCreateTeam(@ModelAttribute("team") Team team, Principal principal) { 
     logger.info("Welcome to the create team page!"); 

     Account owner = accountService.findOneByLogin(principal.getName()); 
     team.setOwner(owner); 
     team.setMembers(new AutoPopulatingList<Account>(Account.class)); 

     return "teams"; 
    } 

    @RequestMapping(value = "/teams/create-team", method = RequestMethod.POST) 
    public String postCreateTeam(@ModelAttribute("team") Team team) { 
     logger.info("Team created!"); 

     teamService.save(team); 

     return "redirect:/teams.html"; 
    } 

Và có dạng:

<form:form commandName="team" id="teamForm"> 
     <div class="form-group"> 
      <label>Name</label> 
      <form:input path="name" cssClass="form-control" /> 
     </div> 
     <div class="form-group" id="row-template"> 
      <label>Members</label> 
      <form:select path="members[0].id" cssClass="form-control" data-live-search="true" > 
      <form:options items="${accounts}" itemValue="id" /> 
      </form:select> 
      ... 
     </div> 
    <form:hidden path="owner.id" /> 
</form:form> 

Tôi đang làm gì sai?

Trả lời

20
teamService.save(team); 

Phương thức lưu chỉ chấp nhận các đối tượng tạm thời. đối tượng thoáng qua bạn có thể tìm

Transient - an object is transient if it has just been instantiated using the new operator, and it is not associated with a Hibernate Session. It has no persistent representation in the database and no identifier value has been assigned. Transient instances will be destroyed by the garbage collector if the application does not hold a reference anymore. Use the Hibernate Session to make an object persistent (and let Hibernate take care of the SQL statements that need to be executed for this transition).

Bạn đang nhận được các đối tượng trong nhóm và bạn đang cố gắng kéo dài nó vào DB là gì nhưng đối tượng đó có đối tượng tài khoản trong đó và đối tượng tài khoản được tách ra (phương tiện ví dụ của đối tượng đó đã lưu vào DB nhưng đối tượng đó không có trong phiên). Hibernate đang cố gắng tiết kiệm nó vì bạn đã xác định:

@OneToMany(cascade = CascadeType.ALL, .... 

Vì vậy, có vài cách làm thế nào bạn có thể sửa chữa nó:

1) không sử dụng cấu hình CascadeType.ALL. Đối tượng tài khoản có thể được sử dụng cho số lượng Đội (ít nhất cấu trúc miền cho phép nó) và hoạt động cập nhật có thể cập nhật Tài khoản cho TẤT CẢ Nhóm - điều đó có nghĩa là không nên bắt đầu thao tác này với Cập nhật nhóm. Tôi sẽ loại bỏ tham số cascade từ đó (giá trị mặc định là không có hoạt động thác), nếu bạn thực sự cần sử dụng cấu hình MERGE/DELETE. Nhưng nếu bạn thực sự cần phải kiên trì thì hãy xem tùy chọn # 2

2) sử dụng phương thức 'saveOrUpdate()' thay vì 'save()'. Phương thức 'saveOrUpdate()' chấp nhận các đối tượng tạm thời và tách rời. Nhưng vấn đề với phương pháp này là trong thiết kế: bạn có thực sự cần chèn/cập nhật tài khoản khi bạn đang lưu đối tượng Nhóm không? Tôi sẽ chia nó thành hai hoạt động và ngăn cập nhật Tài khoản từ Nhóm.

Hy vọng điều này sẽ hữu ích.

+0

Bình chọn giải pháp đầu tiên, đã giúp tôi. – vtomic85

10

Lỗi xảy ra do id được đặt. Hibernate phân biệt giữa các đối tượng tạm thời và tách ra và chỉ hoạt động với các đối tượng tạm thời.

isteamService.save(team); 

đi vào hoạt động này không thể được nạp id vì là @GeneratedValue

+1

Thats câu trả lời perfext, hãy chắc chắn rằng id không có giá trị. –

+1

Ồ, vậy các đối tượng có id có '@ GeneratedValue' thậm chí không thể được lưu nếu id đó đã được đặt? Tôi nghĩ rằng chú thích sẽ chỉ là một loại dự phòng. Tốt để biết nó không phải! – Froxx

+1

Đảm bảo rằng id của bạn không được đặt thành 0 nếu kiểu dữ liệu của bạn là 'Số nguyên' và sẽ ổn nếu id dữ liệu là' int'. – Ram

0

Kể từ id của bạn được tự động tạo ra giá trị, không gửi nó từ phía khách hàng.Tôi đã có một vấn đề tương tự. Đảm bảo rằng bạn không cung cấp giá trị cho thuộc tính được tạo tự động.

Các vấn đề liên quan