Intro
Hi, I encountered a surprising behavior while using Hibernate with a @OneToOne relationship and only CascadeType.PERSIST set.
I expected throwing exception when trying to save a transient child entity without CascadeType.MERGE during a save() (which triggers merge() internally in Spring Data JPA).
But instead of throwing an exception, Hibernate silently persisted the Parent entity, and inserted a Child with all fields being either null or 0 (its ID was generated, though).
Environment
> spring-boot:3.3.12
> spring-data-jpa:3.3.12
> hibernate-core:6.5.3.final
Source Code
@Entity
class Parent(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "parent_id")
val id: Long = 0L,
@OneToOne(cascade = [CascadeType.PERSIST]) // <------- HERE: Only PERSIST
@JoinColumn(name = "child_id")
var child: Child? = null
)
@Entity
class Child(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "child_id")
val id: Long = 0L,
val parentId: Long,
val name: String,
)
@Service
class MyService(
private val parentRepository: ParentRepository
) {
fun create(id: Long) {
val parent = parentRepository.findById(id).orElseThrow()
val child = Child(parentId = id, name = "test")
parent.child = child
parentRepository.save(parent) // <------- triggers merge()
}
}
Result in MySQL
mysql> select * from parent;
+-----------+----------+
| parent_id | child_id |
+-----------+----------+
| 1 | 40 |
+-----------+----------+
mysql> select * from child;
+----------+-----------+------+
| child_id | parent_id | name |
+----------+-----------+------+
| 40 | 0 | NULL |
+----------+-----------+------+
As you can see, Hibernate inserted the Child, even though no cascade MERGE or explicit childRepository.save(child) was used.
The key point is that parent_id = 0 and name = null in child table.
Question
- Why doesn’t Hibernate throw a exception or prevent child record writing?
- Why does it silently insert a Child entity with only the ID populated and other fields null/zero?
- Is this behavior intentional or considered a bug / limitation?

