首页 > 解决方案 > 如何使用 hibernate 5 和 mysql 解决 HHH000346 错误?

问题描述

我正在研究宁静的服务和观点。关于它,我使用mysql和hibernate 5。我的数据表是两个并且具有引用关系。当我更新主键时会出现问题。当我添加新的然后更新另一个表中的现有数据(它们具有引用关系)时,HHH000346:托管刷新期间发生错误。

我已经在谷歌上搜索了,但我找不到答案。

这是我的实体类。

@Entity
@Table(name = "users")
@EntityListeners(AuditingEntityListener.class)
public class User {
    private long serial;
    private String username;
    private String password;

    public User() {

    }

    public User(long serial, String username, String password) {
        setSerial(serial);
        setUsername(username);
        setPassword(password);
    }

    @Column(name = "serial", nullable = false)
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getSerial() {
        return serial;
    }

    public void setSerial(long serial) {
        this.serial = serial;
    }

    @Id
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Column(name = "password", nullable = false)
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "serial: " + this.serial + ", username: " + this.username + ", password: " + this.password; 
    }
}
Entity
@Table(name = "sites")
@EntityListeners(AuditingEntityListener.class)
@IdClass(Site.class)
public class Site implements Serializable{
    @ManyToOne
    @JoinColumn(name="username",foreignKey=@ForeignKey(name="username"))
    private String username;
    private String siteURL;

    @Id
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Id
    public String getSiteURL() {
        return siteURL;
    }

    public void setSiteURL(String siteName) {
        this.siteURL = siteName;
    }
}

这是班级有问题。

public class UserController {

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private SiteRepository siteRepository;
    private CryptoUtil passwordEncoder = new CryptoUtil();

    ...

    @PutMapping("/users/{username}")
    public User updateUser(@PathVariable(value = "username") String username, @Valid @RequestBody User userDetails)
            throws ResourceNotFoundException {
        User user = userRepository.findById(username)
                .orElseThrow(() -> new ResourceNotFoundException("User not found on :: " + username));
        List<Site> sites = siteRepository.findByUsername(user.getUsername());

        userDetails.setPassword(passwordEncoder.encryptSHA256(userDetails.getPassword()));
        final User updateUser = userRepository.save(userDetails);

        for (Site site : sites)
        {
            site.setUsername(userDetails.getUsername());
            site = siteRepository.save(site);
        }

        userRepository.delete(user);
        return updateUser;
    }

    ....
}
The for-each statement occurs error.

PLEASE HELP ME

标签: mysqlspringhibernateweb

解决方案


你为什么要这么做?

@ManyToOne
@JoinColumn(name="username",foreignKey=@ForeignKey(name="username"))
private String username;

它应该是:

@ManyToOne
@JoinColumn(name="username",foreignKey=@ForeignKey(name="username"))
private User user;

我还建议您使用主键作为外键。而且你不能@Id在一个实体中有多个。


推荐阅读