[JIRA] (HHH-15547) Multi-fetch with a single bag returns duplicates
by naizarak (JIRA)
naizarak ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=5ac8b46... ) *updated* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiN2JmZjg0OTM0... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-15547?atlOrigin=eyJpIjoiN2JmZj... ) HHH-15547 ( https://hibernate.atlassian.net/browse/HHH-15547?atlOrigin=eyJpIjoiN2JmZj... ) Multi-fetch with a single bag returns duplicates ( https://hibernate.atlassian.net/browse/HHH-15547?atlOrigin=eyJpIjoiN2JmZj... )
Change By: naizarak ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=5ac8b46... )
Fetching multiple bags isn't allowed and throws a 'MultipleBagFetchException'. However multi-fetching a bag with a non-bag collection is allowed even though it also produces indeterminate indeterminable duplicate values (i.e. can't differentiate deliberate vs cartesian duplicates). Logically this operation should also be illegal, otherwise it yields an incorrect representation of the object state.
# {code:java}package org.hibernate.bugs;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Id;
import jakarta.persistence.Persistence;
import jakarta.persistence.TypedQuery;
public class HHH15547 {
private EntityManagerFactory entityManagerFactory;
@Entity(name = "Library")
public static class Library {
@Id
public Long id;
@ElementCollection
public Set<String> books;
@ElementCollection
public List<String> movies;
}
@BeforeEach
public void init() {
entityManagerFactory = Persistence.createEntityManagerFactory( "templatePU" );
}
@AfterEach
public void destroy() {
entityManagerFactory.close();
}
@Test
public void hhh15547_test() {
doInEM(em -> {
Library lib = new Library();
lib.id = 1L;
lib.books = Set.of("b1", "b2");
lib.movies = List.of("m1", "m2");
em.persist(lib);
});
doInEM(em -> {
TypedQuery<Library> query = em.createQuery(
"SELECT l FROM Library AS l "
+ "LEFT JOIN FETCH l.books "
+ "LEFT JOIN FETCH l.movies",
Library.class);
Library lib = query.getSingleResult();
lib.movies.add("m3");
});
doInEM(em -> {
Library lib = em.find(Library.class, 1L);
// fails, is actually "m1", "m2", "m1", "m2", "m3"
assertEquals(List.of("m1", "m2", "m3"), lib.movies);
});
}
void doInEM(Consumer<EntityManager> function) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
function.accept(entityManager);
entityManager.getTransaction().commit();
entityManager.close();
}
}
{code}
( https://hibernate.atlassian.net/browse/HHH-15547#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-15547#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#100207- sha1:1c92a42 )
2 years, 2 months
[JIRA] (HHH-15547) Multi-fetch with a single bag returns duplicates
by naizarak (JIRA)
naizarak ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=5ac8b46... ) *updated* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiOTA2ZWQ4YjVl... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-15547?atlOrigin=eyJpIjoiOTA2ZW... ) HHH-15547 ( https://hibernate.atlassian.net/browse/HHH-15547?atlOrigin=eyJpIjoiOTA2ZW... ) Multi-fetch with a single bag returns duplicates ( https://hibernate.atlassian.net/browse/HHH-15547?atlOrigin=eyJpIjoiOTA2ZW... )
Change By: naizarak ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=5ac8b46... )
Fetching multiple bags isn't allowed and throws a 'MultipleBagFetchException'. However multi-fetching a bag with a non-bag collection is allowed even though it also produces indeterminate duplicate values (i.e. can't differentiate deliberate vs cartesian duplicates). Logically this operation should also be illegal, otherwise it yields an incorrect representation of the object state.
{code:java}package org.hibernate.bugs;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Id;
import jakarta.persistence.Persistence;
import jakarta.persistence.TypedQuery;
public class HHH15547 {
private EntityManagerFactory entityManagerFactory;
@Entity(name = "Library")
public static class Library {
@Id
public Long id;
@ElementCollection
public Set<String> books;
@ElementCollection
public List<String> movies;
}
@BeforeEach
public void init() {
entityManagerFactory = Persistence.createEntityManagerFactory( "templatePU" );
}
@AfterEach
public void destroy() {
entityManagerFactory.close();
}
@Test
public void hhh15547_test() {
doInEM(em -> {
Library lib = new Library();
lib.id = 1L;
lib.books = Set.of("b1", "b2");
lib.movies = List.of("m1", "m2");
em.persist(lib);
});
doInEM(em -> {
TypedQuery<Library> query = em.createQuery(
"SELECT l FROM Library AS l "
+ "LEFT JOIN FETCH l.books "
+ "LEFT JOIN FETCH l.movies",
Library.class);
Library lib = query.getSingleResult();
lib.movies.add("m3");
});
doInEM(em -> {
Library lib = em.find(Library.class, 1L);
// fails, is actually "m1", "m2", "m1", "m2", "m3"
assertEquals(List.of("m1", "m2", "m3"), lib.movies);
});
}
void doInEM(Consumer<EntityManager> function) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
function.accept(entityManager);
entityManager.getTransaction().commit();
entityManager.close();
}
}
{code}
( https://hibernate.atlassian.net/browse/HHH-15547#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-15547#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#100207- sha1:1c92a42 )
2 years, 2 months