[JIRA] (HHH-16176) OneToMany mappedby inserts duplicate records when saved
by Kevin (JIRA)
Kevin ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=70121%3... ) *created* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiZWZkZjIxMDAw... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-16176?atlOrigin=eyJpIjoiZWZkZj... ) HHH-16176 ( https://hibernate.atlassian.net/browse/HHH-16176?atlOrigin=eyJpIjoiZWZkZj... ) OneToMany mappedby inserts duplicate records when saved ( https://hibernate.atlassian.net/browse/HHH-16176?atlOrigin=eyJpIjoiZWZkZj... )
Issue Type: Bug Affects Versions: 5.6.7 Assignee: Unassigned Components: hibernate-core Created: 13/Feb/2023 04:44 AM Environment: Spring Boot 2.6.6 and Spring Data JPA and Hibernate 5.6.7.Final Priority: Critical Reporter: Kevin ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=70121%3... )
I'm working on a Java project using Spring Boot 2.6.6 and Spring Data JPA, Hibernate 5.6.7.Final and I'm getting a strange behaviour.
<?xml version= "1.0" encoding= "UTF-8" ?>
<project xmlns= "<http://maven.apache.org/POM/4.0.0" >
xmlns:xsi = " <http://www.w3.org/2001/XMLSchema-instance" >
xsi:schemaLocation= " <http://maven.apache.org/POM/4.0.0> <http://maven.apache.org/xsd/maven-4.0.0.xsd" > >
<modelVersion> 4.0.0 </modelVersion>
<parent>
<artifactId> spring-boot-starter-parent </artifactId>
<groupId> org.springframework.boot </groupId>
<relativePath/>
<version> 2.6.6 </version> <!-- lookup parent from repository -->
</parent>
<properties>
<maven.compiler.source> 11 </maven.compiler.source>
<maven.compiler.target> 11 </maven.compiler.target>
</properties>
<dependencies>
<dependency>
<artifactId> spring-boot-starter </artifactId>
<groupId> org.springframework.boot </groupId>
</dependency>
<dependency>
<artifactId> spring-boot-starter-actuator </artifactId>
<groupId> org.springframework.boot </groupId>
</dependency>
<dependency>
<groupId> org.springframework.boot </groupId>
<artifactId> spring-boot-starter-data-jpa </artifactId>
</dependency>
<dependency>
<groupId> com.h2database </groupId>
<artifactId> h2 </artifactId>
<scope> test </scope>
</dependency>
<dependency>
<groupId> org.mariadb.jdbc </groupId>
<artifactId> mariadb-java-client </artifactId>
</dependency>
<dependency>
<artifactId> spring-boot-starter-web </artifactId>
<groupId> org.springframework.boot </groupId>
</dependency>
<dependency>
<groupId> org.springframework.boot </groupId>
<artifactId> spring-boot-starter-test </artifactId>
<scope> test </scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId> org.springframework.boot </groupId>
<artifactId> spring-boot-maven-plugin </artifactId>
</plugin>
</plugins>
</build>
</project>
Consider following entities (getters and setters are omitted for brevity):
@Entity
@Table(name = "user" )
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(cascade = CascadeType.ALL,mappedBy = "user" )
private List<ContactInfo> contactInfos = new ArrayList<>();
@Entity
@Table(name = "contact_info" )
public class ContactInfo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String phoneNumber;
private String address;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "uid" )
private User user;
}
I have already saved the user in the database and want to add a ContactInfo to it.
I use Spring Data JPA and test is written with it.
@Transactional
public User saveUser() { saved the user in the database first
User user = new User();
user.setName( "kevin" );
return userRepository.save(user);
}
@Transactional
public User updateContactInfo( Long id) { // find user from db and add a ContactInfo to it.
User user = userRepository.findById(id).get();
ContactInfo contactInfo = new ContactInfo();
contactInfo.setUser(user);
user.getContactInfos().add(contactInfo);
User saveUser = userRepository.save(user);
System.out.println(saveUser.getContactInfos().size()); //2
return user;
}
After that hibernate perform Merge operation on User entity and Cascade merge on contactInfos collection. I expect that saveUser will have one element in contactInfos collection, but it contains two the same elements. In database created only one.
Can only create thumbnails for attached images
Below is a log of my execution:
2023-02-13 11:03:54.585 INFO 2016 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.6.7.Final
2023-02-13 11:03:54.815 INFO 2016 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2023-02-13 11:03:55.311 INFO 2016 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2023-02-13 11:03:55.631 INFO 2016 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2023-02-13 11:03:55.677 INFO 2016 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
Hibernate:
create table contact_info (
id bigint generated by default as identity,
address varchar(255),
phone_number varchar(255),
uid bigint,
primary key (id)
)
Hibernate:
create table user (
id bigint generated by default as identity,
name varchar(255),
primary key (id)
)
2023-02-13 11:03:56.761 INFO 2016 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2023-02-13 11:03:56.772 INFO 2016 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2023-02-13 11:03:56.943 DEBUG 2016 --- [ main] tor$SharedEntityManagerInvocationHandler : Creating new EntityManager for shared EntityManager invocation
2023-02-13 11:03:57.057 DEBUG 2016 --- [ main] tor$SharedEntityManagerInvocationHandler : Creating new EntityManager for shared EntityManager invocation
2023-02-13 11:03:57.166 DEBUG 2016 --- [ main] tor$SharedEntityManagerInvocationHandler : Creating new EntityManager for shared EntityManager invocation
2023-02-13 11:03:57.230 DEBUG 2016 --- [ main] tor$SharedEntityManagerInvocationHandler : Creating new EntityManager for shared EntityManager invocation
2023-02-13 11:03:57.232 DEBUG 2016 --- [ main] tor$SharedEntityManagerInvocationHandler : Creating new EntityManager for shared EntityManager invocation
2023-02-13 11:03:57.538 WARN 2016 --- [ main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2023-02-13 11:03:58.660 INFO 2016 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 1 endpoint(s) beneath base path '/actuator'
2023-02-13 11:03:58.728 INFO 2016 --- [ main] org.example.service.UserTest : Started UserTest in 6.785 seconds (JVM running for 8.934)
2023-02-13 11:03:58.959 DEBUG 2016 --- [ main] o.s.orm.jpa.JpaTransactionManager : Creating new transaction with name [org.example.service.UserService.saveUser]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2023-02-13 11:03:58.959 DEBUG 2016 --- [ main] o.s.orm.jpa.JpaTransactionManager : Opened new EntityManager [SessionImpl(367559104<open>)] for JPA transaction
2023-02-13 11:03:58.966 DEBUG 2016 --- [ main] o.s.orm.jpa.JpaTransactionManager : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@e594c46]
2023-02-13 11:03:58.982 DEBUG 2016 --- [ main] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [SessionImpl(367559104<open>)] for JPA transaction
2023-02-13 11:03:58.983 DEBUG 2016 --- [ main] o.s.orm.jpa.JpaTransactionManager : Participating in existing transaction
2023-02-13 11:03:58.995 TRACE 2016 --- [ main] o.hibernate.event.internal.EntityState : Transient instance of: org.example.entity.User
2023-02-13 11:03:58.996 TRACE 2016 --- [ main] o.h.e.i.DefaultPersistEventListener : Saving transient instance
2023-02-13 11:03:59.001 TRACE 2016 --- [ main] o.h.e.i.AbstractSaveEventListener : Saving [org.example.entity.User#<null>]
2023-02-13 11:03:59.020 TRACE 2016 --- [ main] o.hibernate.event.internal.WrapVisitor : Wrapped collection in role: org.example.entity.User.contactInfos
Hibernate:
insert
into
user
(id, name)
values
(default, ?)
2023-02-13 11:03:59.033 TRACE 2016 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [kevin]
2023-02-13 11:03:59.049 DEBUG 2016 --- [ main] o.s.orm.jpa.JpaTransactionManager : Initiating transaction commit
2023-02-13 11:03:59.049 DEBUG 2016 --- [ main] o.s.orm.jpa.JpaTransactionManager : Committing JPA transaction on EntityManager [SessionImpl(367559104<open>)]
2023-02-13 11:03:59.050 TRACE 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Flushing session
2023-02-13 11:03:59.050 DEBUG 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Processing flush-time cascades
2023-02-13 11:03:59.051 DEBUG 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Dirty checking collections
2023-02-13 11:03:59.052 TRACE 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Flushing entities and processing referenced collections
2023-02-13 11:03:59.058 TRACE 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Processing unreferenced collections
2023-02-13 11:03:59.059 TRACE 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Scheduling collection removes/(re)creates/updates
2023-02-13 11:03:59.062 DEBUG 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Flushed: 0 insertions, 0 updates, 0 deletions to 1 objects
2023-02-13 11:03:59.062 DEBUG 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Flushed: 1 (re)creations, 0 updates, 0 removals to 1 collections
2023-02-13 11:03:59.063 TRACE 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Executing flush
2023-02-13 11:03:59.066 TRACE 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Post flush
2023-02-13 11:03:59.069 DEBUG 2016 --- [ main] o.s.orm.jpa.JpaTransactionManager : Closing JPA EntityManager [SessionImpl(367559104<open>)] after transaction
2023-02-13 11:03:59.070 DEBUG 2016 --- [ main] o.s.orm.jpa.JpaTransactionManager : Creating new transaction with name [org.example.service.UserService.updateContactInfo]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2023-02-13 11:03:59.070 DEBUG 2016 --- [ main] o.s.orm.jpa.JpaTransactionManager : Opened new EntityManager [SessionImpl(1978865375<open>)] for JPA transaction
2023-02-13 11:03:59.071 DEBUG 2016 --- [ main] o.s.orm.jpa.JpaTransactionManager : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@2d4aadc]
2023-02-13 11:03:59.071 DEBUG 2016 --- [ main] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [SessionImpl(1978865375<open>)] for JPA transaction
2023-02-13 11:03:59.071 DEBUG 2016 --- [ main] o.s.orm.jpa.JpaTransactionManager : Participating in existing transaction
2023-02-13 11:03:59.079 TRACE 2016 --- [ main] o.h.e.internal.DefaultLoadEventListener : Loading entity: [org.example.entity.User#1]
2023-02-13 11:03:59.079 TRACE 2016 --- [ main] o.h.e.internal.DefaultLoadEventListener : Attempting to resolve: [org.example.entity.User#1]
2023-02-13 11:03:59.081 TRACE 2016 --- [ main] o.h.e.internal.DefaultLoadEventListener : Object not resolved in any cache: [org.example.entity.User#1]
Hibernate:
select
user0_.id as id1_1_0_,
user0_.name as name2_1_0_
from
user user0_
where
user0_.id=?
2023-02-13 11:03:59.086 TRACE 2016 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [1]
2023-02-13 11:03:59.098 DEBUG 2016 --- [ main] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [SessionImpl(1978865375<open>)] for JPA transaction
2023-02-13 11:03:59.098 DEBUG 2016 --- [ main] o.s.orm.jpa.JpaTransactionManager : Participating in existing transaction
2023-02-13 11:03:59.099 DEBUG 2016 --- [ main] h.e.i.EntityCopyObserverFactoryInitiator : Configured EntityCopyObserver strategy: disallow
2023-02-13 11:03:59.102 TRACE 2016 --- [ main] o.hibernate.event.internal.EntityState : Persistent instance of: org.example.entity.User
2023-02-13 11:03:59.103 TRACE 2016 --- [ main] o.h.e.i.DefaultMergeEventListener : Ignoring persistent instance
2023-02-13 11:03:59.104 TRACE 2016 --- [ main] o.hibernate.event.internal.EntityState : Transient instance of: org.example.entity.ContactInfo
2023-02-13 11:03:59.105 TRACE 2016 --- [ main] o.h.e.i.DefaultMergeEventListener : Merging transient instance
2023-02-13 11:03:59.105 TRACE 2016 --- [ main] o.h.e.i.DefaultMergeEventListener : Already in merge process
2023-02-13 11:03:59.105 TRACE 2016 --- [ main] o.h.e.i.AbstractSaveEventListener : Saving [org.example.entity.ContactInfo#<null>]
Hibernate:
insert
into
contact_info
(id, address, phone_number, uid)
values
(default, ?, ?, ?)
2023-02-13 11:03:59.106 TRACE 2016 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [null]
2023-02-13 11:03:59.106 TRACE 2016 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [VARCHAR] - [null]
2023-02-13 11:03:59.106 TRACE 2016 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [BIGINT] - [1]
2023-02-13 11:04:05.522 TRACE 2016 --- [ main] DefaultInitializeCollectionEventListener : Initializing collection [org.example.entity.User.contactInfos#1]
2023-02-13 11:04:05.523 TRACE 2016 --- [ main] DefaultInitializeCollectionEventListener : Checking second-level cache
2023-02-13 11:04:05.523 TRACE 2016 --- [ main] DefaultInitializeCollectionEventListener : Collection not cached
Hibernate:
select
contactinf0_.uid as uid4_0_0_,
contactinf0_.id as id1_0_0_,
contactinf0_.id as id1_0_1_,
contactinf0_.address as address2_0_1_,
contactinf0_.phone_number as phone_nu3_0_1_,
contactinf0_.uid as uid4_0_1_
from
contact_info contactinf0_
where
contactinf0_.uid=?
2023-02-13 11:04:05.524 TRACE 2016 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [1]
2023-02-13 11:04:05.530 TRACE 2016 --- [ main] o.h.e.internal.DefaultLoadEventListener : Loading entity: [org.example.entity.ContactInfo#1]
2023-02-13 11:04:05.531 TRACE 2016 --- [ main] o.h.e.internal.DefaultLoadEventListener : Attempting to resolve: [org.example.entity.ContactInfo#1]
2023-02-13 11:04:05.531 TRACE 2016 --- [ main] DefaultInitializeCollectionEventListener : Collection initialized
2
2023-02-13 11:04:36.584 DEBUG 2016 --- [ main] o.s.orm.jpa.JpaTransactionManager : Initiating transaction commit
2023-02-13 11:04:36.585 DEBUG 2016 --- [ main] o.s.orm.jpa.JpaTransactionManager : Committing JPA transaction on EntityManager [SessionImpl(1978865375<open>)]
2023-02-13 11:04:36.585 TRACE 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Flushing session
2023-02-13 11:04:36.585 DEBUG 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Processing flush-time cascades
2023-02-13 11:04:36.586 TRACE 2016 --- [ main] o.hibernate.event.internal.EntityState : Persistent instance of: org.example.entity.ContactInfo
2023-02-13 11:04:36.586 TRACE 2016 --- [ main] o.h.e.i.DefaultPersistEventListener : Ignoring persistent instance
2023-02-13 11:04:36.586 TRACE 2016 --- [ main] o.hibernate.event.internal.EntityState : Persistent instance of: org.example.entity.User
2023-02-13 11:04:36.586 TRACE 2016 --- [ main] o.h.e.i.DefaultPersistEventListener : Ignoring persistent instance
2023-02-13 11:04:36.587 TRACE 2016 --- [ main] o.hibernate.event.internal.EntityState : Persistent instance of: org.example.entity.ContactInfo
2023-02-13 11:04:36.587 TRACE 2016 --- [ main] o.h.e.i.DefaultPersistEventListener : Ignoring persistent instance
2023-02-13 11:04:36.587 TRACE 2016 --- [ main] o.hibernate.event.internal.EntityState : Persistent instance of: org.example.entity.ContactInfo
2023-02-13 11:04:36.587 TRACE 2016 --- [ main] o.h.e.i.DefaultPersistEventListener : Ignoring persistent instance
2023-02-13 11:04:36.587 TRACE 2016 --- [ main] o.hibernate.event.internal.EntityState : Persistent instance of: org.example.entity.ContactInfo
2023-02-13 11:04:36.587 TRACE 2016 --- [ main] o.h.e.i.DefaultPersistEventListener : Ignoring persistent instance
2023-02-13 11:04:36.589 TRACE 2016 --- [ main] o.hibernate.event.internal.EntityState : Persistent instance of: org.example.entity.User
2023-02-13 11:04:36.589 TRACE 2016 --- [ main] o.h.e.i.DefaultPersistEventListener : Ignoring persistent instance
2023-02-13 11:04:36.589 DEBUG 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Dirty checking collections
2023-02-13 11:04:36.589 TRACE 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Flushing entities and processing referenced collections
2023-02-13 11:04:36.589 TRACE 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Processing unreferenced collections
2023-02-13 11:04:36.589 TRACE 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Scheduling collection removes/(re)creates/updates
2023-02-13 11:04:36.590 DEBUG 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Flushed: 0 insertions, 0 updates, 0 deletions to 2 objects
2023-02-13 11:04:36.591 DEBUG 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Flushed: 0 (re)creations, 1 updates, 0 removals to 1 collections
2023-02-13 11:04:36.591 TRACE 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Executing flush
2023-02-13 11:04:36.593 TRACE 2016 --- [ main] o.h.e.i.AbstractFlushingEventListener : Post flush
2023-02-13 11:04:36.594 DEBUG 2016 --- [ main] o.s.orm.jpa.JpaTransactionManager : Closing JPA EntityManager [SessionImpl(1978865375<open>)] after transaction
2023-02-13 11:04:36.624 INFO 2016 --- [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2023-02-13 11:04:36.628 INFO 2016 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2023-02-13 11:04:36.654 INFO 2016 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
I found that other people had raised the same question, but it still didn't seem to be solved. The following links are for reference.
* https://stackoverflow.com/questions/7903800/hibernate-inserts-duplicates-... ( https://stackoverflow.com/questions/7903800/hibernate-inserts-duplicates-... )
* https://hibernate.atlassian.net/browse/HHH-14078 ( https://hibernate.atlassian.net/browse/HHH-14078 )
* https://github.com/spring-projects/spring-data-jpa/issues/2795 ( https://github.com/spring-projects/spring-data-jpa/issues/2795 )
Has anyone could tell me what the problem is and how to fix it? I would really appreciate it.Thanks.
( https://hibernate.atlassian.net/browse/HHH-16176#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-16176#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100215- sha1:b88b0a4 )
1 year, 11 months