在Hibernate中保持一对一关系实体 - 实体是分离的

时间:2014-12-02 15:27:55

标签: java hibernate jpa one-to-one

我有一对一的关系表:

用户:

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 [appServlet]的Servlet.service()在路径[/ ibank]的上下文中引发异常[请求处理失败;嵌套异常是javax.persistence.PersistenceException:org.hibernate.PersistentObjectException:传递给persist的分离实体:pl.piotr.ibank.model.User]具有根本原因   org.hibernate.PersistentObjectException:传递给persist的分离实体:pl.piotr.ibank.model.User

userRole.setUser(user); userRoleService.createUserRole(userRole);可以保存好,但是当我尝试ua.setUser(user); userAccountService.createUserAccount(ua);时,我会获得分离的实体

1 个答案:

答案 0 :(得分:1)

将主键同时作为外键是非常不好的做法。特别是当你有@GeneratedValue时。

仔细看看,您的实体映射正常但usersAccounts表需要调整。从id列中删除该外键约束,并添加新列userId,该列将是users#id的外键。一切都应该在那之后发挥作用。