Bi-directional OneToMany to child with SINGLE_TABLE interitance - the parent modification cause SQL insert instead of update


Looks like there is a regression in Hibernate 6 compared to Hibernate 5 where I don’t see such issue.

In bi-directional OneToMany association to child entity with SINGLE_TABLE interitance the parent modification trigger SQL insert insetad of SQL update. So one more entity

Let’s say we have the parent entity called Whiteboard

public class Whiteboard {

	@GeneratedValue(strategy = GenerationType.SEQUENCE)
	private Long id;

	@OneToMany(fetch = FetchType.LAZY, mappedBy = "whiteboard", cascade = CascadeType.ALL, orphanRemoval = true)
	private final List<Circle> circles = new ArrayList<>();

	private String name;

	public void addCircle(Circle circle) {

and child entity

public class Circle extends Shape {

	@ManyToOne(fetch = FetchType.LAZY)
	private Whiteboard whiteboard;

inherited from

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "shapeType", discriminatorType = DiscriminatorType.INTEGER)
public abstract class Shape {

	@GeneratedValue(strategy = GenerationType.SEQUENCE)
	private Long id;

	@Column(insertable = false, updatable = false)
	private ShapeType shapeType;

And repository

public interface WhiteboardRepo extends JpaRepository<Whiteboard, Long> {

	List<Whiteboard> findAllByName(String name);

And finally ShapeType enum

public enum ShapeType {

	public static final String ORDINAL_CIRCLE = "0";
	public static final String ORDINAL_SQUARE = "1";

The next test will fail. Both assertThat() will fail, you can reorder them to see it.

class DemoApplicationTests {

	@Autowired private WhiteboardRepo whiteboardRepo;

	void init() {

		Whiteboard wb = new Whiteboard();

	void testNoInsertWhenUpdateIsExpected() {

		Whiteboard wb = whiteboardRepo.findAllByName("my-board").stream().findAny().orElseThrow();
		long whiteboardId = wb.getId();




The problem is that Hibernate will insert new Whiteboard entity to database instead of updating existing one. The reason is because on repository save() method Hibernate will check if such entry already exists in database. For that Hibernate generates the next query:

        whiteboard wb 
    left join
        shape shp on 

The query uses LEFT JOIN, but because of WHERE shp.shape_type=0 the query in becomes effectively an INNER JOIN and returns no rows when Whiteboard exists, but has no related circles (the shape table is empty).

I use org.hibernate.orm:hibernate-core:jar:6.1.5.Final in my Spring Boot 3 project (parent POM is org.springframework.boot:spring-boot-starter:jar:3.0.0). If needed I can provide corresponding demo project, but cannot upload ZIP here.

Thanks for help and if this really a bug, would be nice to fix in the future releases of Hibernate.

I think this is the same issue as [HHH-15902] - Hibernate JIRA
Please watch that issue for updates as we will fix it as part of that.