If an entity is mapped via an XML file, an ElementCollection cannot be annotated with OnDelete because hibernate complains that JoinColumn is missing. But JoinColumn is actually there.
The error message is
{quote}Unidirectional one-to-many associations annotated with @OnDelete must define @JoinColumn{quote}
The following test case demonstrates this behavior. Change the TRIGGER_BUG flag to observe how the test case is working when not using the XML file and how the bug occurs when using the XML file.
TODO{code: insertjava}/* * Copyright 2014 JBoss Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.hibernate.bugs;
import jakarta.persistence.*; import org.hibernate.annotations.LazyCollection; import org.hibernate.annotations.LazyCollectionOption; import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDeleteAction; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.junit.Test;
import java.util.Collections; import java.util.HashSet; import java.util.Set;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.hasSize;
/** * This test case once demonstrates that Hibernate 6.1.3 and earlier complains about a missing * JoinColumn annotation, although this annotation is clearly there. */ public class TestHHH15510 extends BaseCoreFunctionalTestCase {
private static final boolean TRIGGER_BUG = true;
@Entity @Table(name = "entity_hhh15510") public static class EntityHHH15510 { @Id private Long id;
public EntityHHH15510() { }
public void setId(Long id) { this.id = id; }
@ElementCollection @CollectionTable( name = "entity_hhh15510_strings", joinColumns = @JoinColumn(name = "parent") ) @LazyCollection(LazyCollectionOption.FALSE) @JoinColumn(name = "parent") @OnDelete(action = OnDeleteAction.CASCADE) private Set<String> strings = new HashSet<>();
public void addString(String str) { strings.add(str); }
public Set<String> getStrings() { return Collections.unmodifiableSet(strings); } }
@Override protected Class<?>[] getAnnotatedClasses() { return TRIGGER_BUG ? NO_CLASSES : new Class[]{EntityHHH15510.class}; }
@Override protected String[] getMappings() { return TRIGGER_BUG ? new String[]{"mappings.xml"} : NO_MAPPINGS; }
@Test public void hhh15510Test() { // persist a new entity try (final var s = openSession()) { final var tx = s.beginTransaction(); final var e = new EntityHHH15510(); e.setId(1L); e.addString("test01"); e.addString("test02"); s.persist(e); tx.commit(); }
// verify that the issue ID entity was correctly persisted try (final var s = openSession()) { final var tx = s.beginTransaction(); final var e = s.get(EntityHHH15510.class, 1L); final var strings = e.getStrings(); assertThat(strings, hasSize(2)); assertThat(strings, containsInAnyOrder("test01", "test02")); tx.commit(); }
// natively check that child entries are present and natively delete the parent entity try (final var s = openSession()) { final var tx = s.beginTransaction(); final var strings = s.createNativeQuery("select strings from entity_hhh15510_strings", String.class).list(); assertThat(strings, hasSize(2)); assertThat(strings, containsInAnyOrder("test01", "test02")); s.createNativeMutationQuery("delete from entity_hhh15510").executeUpdate(); tx.commit(); }
// natively check that child table is created empty (i.e. on delete cascade did its job) try (final var s = openSession()) { final var tx = s.beginTransaction(); final var strings = s.createNativeQuery("select strings from entity_hhh15510_strings", String.class).list(); assertThat(strings, hasSize(0)); tx.commit(); } } } {code}
The mappings.xml:
{code:xml}<?xml version="1.0" encoding="UTF-8"?> <entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" version="1.0"> <entity class="org.hibernate.bugs.TestHHH15510$EntityHHH15510"/> </entity-mappings> {code} |
|