2014-12-02 83 views
0

我有一個關係一個兩代表一:堅持以一對一的關係實體在休眠 - 實體分離

用戶:

create table users (

    id int not null primary key, 
    username varchar2(40) not null unique, 
    password varchar2(60) not null, 
    firstName varchar2(40) not null, 
    lastName varchar2(40) not null, 
    personalId varchar2(11) unique, 
    city varchar2(40), 
    address varchar2(40), 
    email varchar2(40) not null unique, 
    phone varchar2(9) unique 
); 

UsersAccounts

create table usersAccounts (
    id int primary key, 
    accountNr varchar2(26) not null unique, 
    balance float not null, 
    createDate date not null, 
    expiredDate date, 
    lastCharge date, 
    userId int constraint userAccount_fk_user references users(id), 
); 

我的實體:

用戶

@Entity 
@Table(name = "users") 
public class User implements Serializable { 

    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue 
    @Column(name = "id") 
    private Integer id; 
    @NotBlank 
    @NotNull 
    @Size(min = 3, max = 40) 
    @Column(name = "username") 
    private String username; 
    @NotBlank 
    @NotNull 
    @Size(min = 3, max = 60) 
    @Column(name = "password") 
    private String password; 
    @NotBlank 
    @NotNull 
    @Size(min = 3, max = 40) 
    @Column(name = "firstName") 
    private String firstName; 
    @NotBlank 
    @NotNull 
    @Size(min = 3, max = 40) 
    @Column(name = "lastName") 
    private String lastName; 
    @Size(min = 11, max = 11) 
    @Column(name = "personalId") 
    private String personalId; 
    @Size(max = 40) 
    @Column(name = "city") 
    private String city; 
    @Size(max = 40) 
    @Column(name = "address") 
    private String address; 
    @NotBlank 
    @NotNull 
    @Email 
    @Size(max = 40) 
    @Column(name = "email") 
    private String email; 
    @Size(min = 9, max = 9) 
    @Column(name = "phone") 
    private String phone; 
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    private Set<UserRole> userRoleSet; 
    @OneToOne(mappedBy = "user") 
    private UserAccount userAccount; 

UserAccount

@Entity 
@Table(name = "usersAccounts") 
public class UserAccount implements Serializable { 

    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue 
    @Column(name = "id") 
    private Integer id; 
    @NotNull 
    @Column(name = "accountNr") 
    private String accountNr; 
    @NotNull 
    @Column(name = "balance") 
    private float balance; 
    @NotNull 
    @Column(name = "createDate") 
    private Date createDate; 
    @Column(name = "expiredDate") 
    private Date expiredDate; 
    @Column(name = "lastCharge") 
    private Date lastCharge; 
    @OneToOne(cascade = CascadeType.ALL) 
    @JoinColumn(name = "userId") 
    private User user; 

我試着堅持這一點,但我有錯誤:

@RequestMapping(value = "/admin/addAdmin", method = RequestMethod.POST) 
public String addAdmin(@ModelAttribute("user") UserDto userDto, 
     BindingResult result) { 
    AddUserValidator addUserValidator = new AddUserValidator(); 
    addUserValidator.validate(userDto, result); 
    if (result.hasErrors()) { 
     return "admin/addadmin"; 
    } else { 
     ErrorMessage errorMessage; 
     User user = prepareModelUser(userDto); 
     if ((errorMessage = userService.createUser(user)) != null) { 
      result.rejectValue(errorMessage.getPath(), 
        errorMessage.getDescription()); 
      return "admin/addadmin"; 
     } else { 
      user = userService.findByUsername(user.getUsername()); 
      UserRole userRole = new UserRole("ROLE_ADMIN"); 
      userRole.setUser(user); 
      userRoleService.createUserRole(userRole); 
      UserAccount ua = new UserAccount(); 
      ua.setAccountNr("12345678901"); 
      ua.setBalance(100); 
      DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy"); 
      Date date = new Date(); 
      String dateStr = dateFormat.format(date); 
      try { 
       ua.setCreateDate(dateFormat.parse(dateStr)); 
      } catch (ParseException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      user = userService.findUser(user.getId()); 
      ua.setUser(user); 
      userAccountService.createUserAccount(ua); 
      return "redirect:/admin/adminlist"; 
     } 
    } 
} 

當我嘗試堅持我得到這個錯誤:

SEVERE: Servlet.service() for servlet [appServlet] in context with path [/ibank] threw exception [Request processing failed; nested exception is javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: pl.piotr.ibank.model.User] with root cause org.hibernate.PersistentObjectException: detached entity passed to persist: pl.piotr.ibank.model.User

userRole.setUser(user); userRoleService.createUserRole(userRole);節約不錯,但當我嘗試ua.setUser(user); userAccountService.createUserAccount(ua);我得到分離實體

回答

1

將主鍵同時設爲外鍵是非常糟糕的做法。特別是當你有@GeneratedValue就可以了。

仔細一看,您的實體映射正常,但usersAccounts表需要調整。從id列中刪除該外鍵約束,並添加新列userId,這將是外鍵users#id。之後的一切都應該有效。

+0

我編輯了我的第一篇文章。我利用了你的建議,並在數據庫中編輯了我的表格。但是,當我嘗試堅持我得到新的錯誤。實體用戶被分離。爲什麼? @Predrag Maric – 2014-12-02 16:41:43

+0

很難說,不看服務代碼。嘗試簡化您的代碼,並堅持一個UserAccount相關的用戶。當你成功時,添加其他代碼部分並查看哪個部分導致了問題。你應該爲此編寫一個單元測試,這對外部的人來說很難在這個代碼中導航。 – 2014-12-02 16:54:06