Home Hibernate inserts duplicates after introducing base entity
Reply: 0

Hibernate inserts duplicates after introducing base entity

user2810
1#
user2810 Published in May 22, 2018, 9:22 pm

I tried to introduce a base entity to my Spring Boot application but now Hibernate inserts duplicate entries. The app uses Spring Data JPA and Hibernate for persistence.

My code before looked something like this:

@Entity
public class PasswordResetCode {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    @ManyToOne
    private User user;
    @Column(unique = true)
    private String code;

    public PasswordResetCode(User user, String code) {
        this.user = user;
        user.addPasswordResetCode(this);
        this.code = code;
    }

    // ...

}

@Entity
@Table(name = "\"user\"")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "user", orphanRemoval = true)
    private Set<PasswordResetCode> passwordResetCodes = new HashSet<>();

    public void addPasswordResetCode(PasswordResetCode passwordResetCode) {
        this.passwordResetCodes.add(passwordResetCode);
    }

    // ...    
}

I create a PasswordResetCode like this:

User user = userRepository.findOne(id);
passwordResetCodeRepository.save(new PasswordResetCode(user, "some code"));

This works perfectly fine and the PasswordResetCode only gets inserted once into the database and the reference in the User objects Set gets updated with the persisted PasswordResetCode.

Now I introduced a BaseEntity, removed the id fields from the User and PasswordReset class and let them extend BaseEntity. The BaseEntity looks like this:

@MappedSuperclass
public abstract class BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private long id = 0;

    // getter & setter

}

I create the PasswordResetCode like before but now I get the following error because Hibernate tries to insert the code twice:

could not execute statement; SQL [n/a]; constraint ["UK_JIAB2A9LLEHA81LWDNYRL9RQ0_INDEX_2 ON PUBLIC.PASSWORD_RESET_CODE(CODE) VALUES ('some code', 115)"

Now I realize that I can either remove the cascade in User or save the PasswordResetCode through the User/UserRepository but I want to understand what is happening.

Why can Hibernate see that the PasswordResetCode in the User set is the same that he saved through the repository although it gets added before it is persisted? And why does it fail after the BaseEntity is added?

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.366074 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO