【问题标题】:Hibernate OneToOne bidirectional functionality not workingHibernate OneToOne 双向功能不起作用
【发布时间】:2021-06-18 07:56:03
【问题描述】:

用户表没有自动保存 PasswordInfo 对象 这是我的实体

用户实体

@Entity
@Table(name = "user")
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;
    
    @Column(name = "name")
    private String name;

    @Column(name = "username")
    private String userName;

    @Column(name = "password")
    private String password;
    
    @Column(name = "emp_id")
    private int empId;
    
    @Column(name = "designation")
    private String designation;
    
    @Column(name = "status")
    private String status;
    
    @Column(name = "email_id")
    private String emailId;
    
    @Column(name = "account_status")
    private String accountStatus;
    
    @Column(name = "validity_date")
    private Date validityDate;
    
    @Column(name = "deactivation_date")
    private Date deactivationDate;
    
    @Column(name = "deactivated_by")
    private String deactivatedBy;
    
    @Column(name = "deactivation_remarks")
    private String deactivationRemarks;
    
    @OneToMany(fetch = FetchType.LAZY,
            mappedBy = "user",
            cascade = {CascadeType.PERSIST,CascadeType.MERGE,
                    CascadeType.DETACH,CascadeType.REFRESH})
    private List<LoginDetails> loginDetails;
    
    // add convenience methods for bi-directional relationship for LoginDetails
    public void add(LoginDetails tempLoginDetails) {
        if(loginDetails == null) {
            loginDetails = new ArrayList<LoginDetails>();
        }
        
        loginDetails.add(tempLoginDetails);
        
        tempLoginDetails.setUser(this);
    }
    
    @OneToOne(mappedBy = "user", fetch = FetchType.LAZY,
            cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,
                        CascadeType.REFRESH})
    private PasswordInfo passwordInfo;
    
    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(name = "users_roles", 
    joinColumns = @JoinColumn(name = "user_id"), 
    inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Collection<Role> roles;
    
    @ManyToOne(fetch = FetchType.LAZY,cascade= {CascadeType.PERSIST,CascadeType.MERGE,
            CascadeType.DETACH,CascadeType.REFRESH})
    @JoinColumn(name="department_id")
    private Department department;
    
    @ManyToOne(fetch = FetchType.LAZY,cascade= {CascadeType.PERSIST,CascadeType.MERGE,
            CascadeType.DETACH,CascadeType.REFRESH})
    @JoinColumn(name="branch_id")
    private Branch branch;
    
    /*  
     * TIMESTAMPS START
     * */
    
    @Temporal( TemporalType.TIMESTAMP )
    @CreationTimestamp
    @Column(name = "creation_date")
    private Date creationDate;
    
    @UpdateTimestamp
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "updation_date")
    private Date updationDate;
    
    @ManyToOne(fetch = FetchType.LAZY,cascade={CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,
            CascadeType.REFRESH})
    @JoinColumn(name="created_by")
    private User createdBy;

    @OneToMany(mappedBy="createdBy")
    private Set<User> createdBySet = new HashSet<User>();
    
    @ManyToOne(fetch = FetchType.LAZY,cascade={CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,
            CascadeType.REFRESH})
    @JoinColumn(name="updated_by")
    private User updatedBy;

    @OneToMany(mappedBy="updatedBy")
    private Set<User> updatedBySet = new HashSet<User>();
    
    @PrePersist
    protected void onCreate() {
        creationDate = new Date();
    }

    @PreUpdate
    protected void onUpdate() {
        updationDate = new Date();
    }
    
    /*  
     * TIMESTAMPS END
     * */
    
    public User() {

    }

//  getter and setters and imports are written in real code, i have omitted them here
    
    
}

密码信息实体

@Entity
@Table(name = "password_info")
public class PasswordInfo {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;
    
    @Column(name = "last_password_1")
    private String lastPassword1;
    
    @Column(name = "last_password_2")
    private String lastPassword2;
    
    @Column(name = "last_password_3")
    private String lastPassword3;
    
    @Column(name = "last_password_4")
    private String lastPassword4;
    
    @Column(name = "last_password_5")
    private String lastPassword5;
    
    @Column(name = "forced_password_flag")
    private String forcedPasswordFlag;
    
    @Column(name = "pass_count")
    private int passCount;
    
    @Column(name = "password_date")
    private Date passwordDate;
    
    @OneToOne(fetch = FetchType.LAZY,cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,
            CascadeType.REFRESH})
    @JoinColumn(name="user_id")
    private User user;
    
    @Temporal( TemporalType.TIMESTAMP )
    @CreationTimestamp
    @Column(name = "creation_date")
    private Date creationDate;
    
    @PrePersist
    protected void onCreate() {
        creationDate = new Date();
    }
    
    public PasswordInfo() {

    }

    //  getter and setters and imports are written in real code, i have omitted them here
}

这是我在服务类中的保存方法

@Override
    @Transactional
    public String save(ReportUser reportUser) {
        User user = new User();
         // assign user details to the user object
        user.setUserName(reportUser.getUserName());
        user.setPassword(passwordEncoder.encode(reportUser.getPassword()));
        user.setName(reportUser.getName());
        user.setEmpId(reportUser.getEmpId());
        user.setDesignation(reportUser.getDesignation());
        user.setEmailId(reportUser.getEmailId());
        user.setStatus(reportUser.getStatus());
        user.setEmailId(reportUser.getEmailId());
        user.setAccountStatus(reportUser.getAccountStatus());
        user.setValidityDate(reportUser.getValidityDate());
        
        String loggedInUser = jwtUtil.getUsername();
        
        logger.info(">>>>> Logged In USER " + loggedInUser);
        
        Department theDepartment = departmentDao.getDepartment(reportUser.getDepartmentId());
        
        Branch theBranch = branchDao.getBranch(reportUser.getBranchId());
        
        User createdByUser = userDao.findByUserName(loggedInUser);
        
        user.setBranch(theBranch);
        user.setDepartment(theDepartment);
        user.setCreatedBy(createdByUser);
        
        
        String[] roleArr = reportUser.getFormRole().split(",");
        
        List<Role> roleList = new ArrayList<Role>();
        
        for(String r: roleArr) {
            roleList.add(roleDao.findRoleByName(r));
        }
                        
        Collection<Role> roles = roleList;
        
        user.setRoles(roles);
        
        ParameterMst pmst = otherDao.getParameterValueById(1L);
        
        int passwordExpirationDays = Integer.valueOf(pmst.getValue());
        
        PasswordInfo pInfo = new PasswordInfo();
        
        // Add passwordExpirationDays to current date
        Date passwordExpirationDate =  DateUtils.asDate(LocalDate.now().plusDays(passwordExpirationDays));
        
        logger.info(">>>>> Password Expiration Date " + passwordExpirationDate);
        
        pInfo.setPasswordDate(passwordExpirationDate);
        pInfo.setPassCount(12);
        pInfo.setUser(user);
        
        user.setPasswordInfo(pInfo);
        
        
        
         // save user in the database
        userDao.save(user);
    
        
        return user.getUserName();
    }

这是保存在 DAO 实现中

@Override
    public void save(User user) {
        // get current hibernate session
        Session currentSession = sessionFactory.getCurrentSession();

        currentSession.saveOrUpdate(user);

    }

由于在用户中设置了双向关系,我应该能够一次性更新两者,而不是单独进行。 为什么这不起作用?

请帮忙!

【问题讨论】:

标签: java hibernate spring-mvc orm


【解决方案1】:

不要同时使用 mappedBy 和 @JoinColumn,因为它们的用途略有不同。

查看两者的用途并使用其中之一。

尝试从 PasswordInfo 实体中删除 @JoinColumn 注释。

【讨论】:

  • 我删除了@JoinColumn(name="user_id"),但它仍然只插入用户,但我无法理解,如果我删除JoinColumn,那么它如何知道与列user_id的关系。
【解决方案2】:

尝试这样注释

在 PasswordInfo 类中:

@OneToOne(mappedBy = "passwordInfo")
private User user;

在用户类中

@OneToOne()
private PasswordInfo passwordInfo;

mappedBy 说 User 表是使用其属性 passwordInfo 的关系的所有者。

【讨论】:

  • 不,它不工作,错误:`org.hibernate.AnnotationException:未知的 mappedBy 在:com.arthfc.report.entity.PasswordInfo.user,引用的属性未知:com.arthfc.report.entity。 User.passwordInfo`
  • 很奇怪它没有找到 User.passwordInfo 属性。尝试删除 User.passwordInfo 上的 mappedBy 属性。
  • 还是不行,我还没有添加 user.add 方法,是这个问题吗?我认为在 OneToOne 中它会自动处理
  • @shah-123 你试过更新后的映射了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-14
  • 2013-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-14
  • 1970-01-01
相关资源
最近更新 更多