HHH-15910 Add static remove methods to Hibernate.class
Signed-off-by: Jan Schatteman <jschatte@redhat.com>
This commit is contained in:
parent
e0f55e5d53
commit
d8bf649998
|
@ -233,6 +233,57 @@ public final class Hibernate {
|
|||
: list.get(key);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the value associated with the given key by the given persistent
|
||||
* map, without fetching the state of the map from the database.
|
||||
*
|
||||
* @param map a persistent map associated with an open session
|
||||
* @param key a key belonging to the map
|
||||
* @return the previous value associated by the map with the given key, or null if there was no value associated
|
||||
* with the given key
|
||||
*
|
||||
* @since 6.2.0
|
||||
*/
|
||||
public static <K, V> V remove(Map<? super K, V> map, K key) {
|
||||
return ( map instanceof PersistentMap )
|
||||
? ( (PersistentMap<K, V>) map ).queuedRemove( key )
|
||||
: map.remove( key );
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the specified element of the given persistent set,
|
||||
* without fetching the state of the set from the database.
|
||||
*
|
||||
* @param set a persistent set associated with an open session
|
||||
* @param element an element belonging to the set
|
||||
* @return true if this set contained the specified element
|
||||
*
|
||||
* @since 6.2.0
|
||||
*/
|
||||
public static <T> boolean remove(Set<T> set, T element) {
|
||||
return ( set instanceof PersistentSet )
|
||||
? ( (PersistentSet<T>) set ).queuedRemove( element )
|
||||
: set.remove( element );
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the specified element of the given persistent list,
|
||||
* without fetching the state of the list from the database.
|
||||
*
|
||||
* @param list a persistent list associated with an open session
|
||||
* @param element an element belonging to the list
|
||||
* @return true if this list contained the specified element
|
||||
*
|
||||
* @since 6.2.0
|
||||
*/
|
||||
public static <T> boolean remove(List<T> list, T element) {
|
||||
return ( list instanceof PersistentList )
|
||||
? ( (PersistentList<T>) list ).queuedRemove( element )
|
||||
: ( list instanceof PersistentBag )
|
||||
? ( (PersistentBag<T>) list ).queuedRemove( element )
|
||||
: list.remove( element );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the true, underlying class of a proxied entity. This operation will
|
||||
* initialize a proxy by side effect.
|
||||
|
|
|
@ -32,7 +32,8 @@ import java.util.Map;
|
|||
* <li>Use static methods of {@link org.hibernate.Hibernate},
|
||||
* for example {@link org.hibernate.Hibernate#size(Collection)},
|
||||
* {@link org.hibernate.Hibernate#contains(Collection, Object)},
|
||||
* or {@link org.hibernate.Hibernate#get(Map, Object)} instead
|
||||
* {@link org.hibernate.Hibernate#get(Map, Object)}, or
|
||||
* {@link org.hibernate.Hibernate#remove(Map, Object)} instead
|
||||
* of {@code LazyCollection(EXTRA)}.
|
||||
* </ul>
|
||||
*/
|
||||
|
|
|
@ -26,7 +26,8 @@ import java.util.Map;
|
|||
* <li>Use static methods of {@link org.hibernate.Hibernate},
|
||||
* for example {@link org.hibernate.Hibernate#size(Collection)},
|
||||
* {@link org.hibernate.Hibernate#contains(Collection, Object)},
|
||||
* or {@link org.hibernate.Hibernate#get(Map, Object)} instead
|
||||
* {@link org.hibernate.Hibernate#get(Map, Object)}, or
|
||||
* {@link org.hibernate.Hibernate#remove(Map, Object)} instead
|
||||
* of {@code LazyCollection(EXTRA)}.
|
||||
* </ul>
|
||||
*/
|
||||
|
|
|
@ -616,7 +616,7 @@ public abstract class AbstractPersistentCollection<E> implements Serializable, P
|
|||
);
|
||||
}
|
||||
|
||||
private void throwLazyInitializationExceptionIfNotConnected() {
|
||||
void throwLazyInitializationExceptionIfNotConnected() {
|
||||
if ( !isConnectedToSession() ) {
|
||||
throwLazyInitializationException( "no session or session was closed" );
|
||||
}
|
||||
|
@ -625,7 +625,7 @@ public abstract class AbstractPersistentCollection<E> implements Serializable, P
|
|||
}
|
||||
}
|
||||
|
||||
private void throwLazyInitializationException(String message) {
|
||||
void throwLazyInitializationException(String message) {
|
||||
throw new LazyInitializationException(
|
||||
"failed to lazily initialize a collection" +
|
||||
(role == null ? "" : " of role: " + role) +
|
||||
|
|
|
@ -18,6 +18,8 @@ import java.util.Map;
|
|||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.Internal;
|
||||
import org.hibernate.engine.spi.CollectionEntry;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
|
@ -404,6 +406,27 @@ public class PersistentBag<E> extends AbstractPersistentCollection<E> implements
|
|||
}
|
||||
}
|
||||
|
||||
@Internal
|
||||
public boolean queuedRemove(Object element) {
|
||||
final CollectionEntry entry = getSession().getPersistenceContextInternal().getCollectionEntry( PersistentBag.this );
|
||||
if ( entry == null ) {
|
||||
throwLazyInitializationExceptionIfNotConnected();
|
||||
throwLazyInitializationException("collection not associated with session");
|
||||
}
|
||||
else {
|
||||
final CollectionPersister persister = entry.getLoadedPersister();
|
||||
if ( hasQueuedOperations() ) {
|
||||
getSession().flush();
|
||||
}
|
||||
if ( persister.elementExists( entry.getLoadedKey(), element, getSession() ) ) {
|
||||
elementRemoved = true;
|
||||
queueOperation( new PersistentBag.SimpleRemove( (E) element ) );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
read();
|
||||
|
@ -633,4 +656,16 @@ public class PersistentBag<E> extends AbstractPersistentCollection<E> implements
|
|||
bag.add( getAddedInstance() );
|
||||
}
|
||||
}
|
||||
|
||||
final class SimpleRemove extends AbstractValueDelayedOperation {
|
||||
|
||||
public SimpleRemove(E orphan) {
|
||||
super( null, orphan );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void operate() {
|
||||
bag.remove( getOrphan() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ import java.util.ListIterator;
|
|||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.Internal;
|
||||
import org.hibernate.engine.spi.CollectionEntry;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
|
@ -217,6 +219,27 @@ public class PersistentList<E> extends AbstractPersistentCollection<E> implement
|
|||
}
|
||||
}
|
||||
|
||||
@Internal
|
||||
public boolean queuedRemove(Object element) {
|
||||
final CollectionEntry entry = getSession().getPersistenceContextInternal().getCollectionEntry( PersistentList.this );
|
||||
if ( entry == null ) {
|
||||
throwLazyInitializationExceptionIfNotConnected();
|
||||
throwLazyInitializationException("collection not associated with session");
|
||||
}
|
||||
else {
|
||||
final CollectionPersister persister = entry.getLoadedPersister();
|
||||
if ( hasQueuedOperations() ) {
|
||||
getSession().flush();
|
||||
}
|
||||
if ( persister.elementExists( entry.getLoadedKey(), element, getSession() ) ) {
|
||||
elementRemoved = true;
|
||||
queueOperation( new PersistentList.SimpleRemove( (E) element ) );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> coll) {
|
||||
read();
|
||||
|
|
|
@ -15,8 +15,11 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.Internal;
|
||||
import org.hibernate.engine.spi.CollectionEntry;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
|
@ -192,6 +195,28 @@ public class PersistentMap<K,E> extends AbstractPersistentCollection<E> implemen
|
|||
return map.remove( key );
|
||||
}
|
||||
|
||||
@Internal
|
||||
public E queuedRemove(Object key) {
|
||||
final CollectionEntry entry = getSession().getPersistenceContextInternal().getCollectionEntry( PersistentMap.this );
|
||||
if ( entry == null ) {
|
||||
throwLazyInitializationExceptionIfNotConnected();
|
||||
throwLazyInitializationException("collection not associated with session");
|
||||
}
|
||||
else {
|
||||
final CollectionPersister persister = entry.getLoadedPersister();
|
||||
if ( hasQueuedOperations() ) {
|
||||
getSession().flush();
|
||||
}
|
||||
Object element = persister.getElementByIndex( entry.getLoadedKey(), key, getSession(), getOwner() );
|
||||
if ( element != null ) {
|
||||
elementRemoved = true;
|
||||
queueOperation( new Remove( (K) key, (E) element ) );
|
||||
return (E) element;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends K,? extends E> puts) {
|
||||
if ( puts.size() > 0 ) {
|
||||
|
|
|
@ -16,6 +16,8 @@ import java.util.Set;
|
|||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.Internal;
|
||||
import org.hibernate.engine.spi.CollectionEntry;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
|
@ -223,6 +225,27 @@ public class PersistentSet<E> extends AbstractPersistentCollection<E> implements
|
|||
}
|
||||
}
|
||||
|
||||
@Internal
|
||||
public boolean queuedRemove(Object element) {
|
||||
final CollectionEntry entry = getSession().getPersistenceContextInternal().getCollectionEntry( PersistentSet.this );
|
||||
if ( entry == null ) {
|
||||
throwLazyInitializationExceptionIfNotConnected();
|
||||
throwLazyInitializationException("collection not associated with session");
|
||||
}
|
||||
else {
|
||||
final CollectionPersister persister = entry.getLoadedPersister();
|
||||
if ( hasQueuedOperations() ) {
|
||||
getSession().flush();
|
||||
}
|
||||
if ( persister.elementExists( entry.getLoadedKey(), element, getSession() ) ) {
|
||||
elementRemoved = true;
|
||||
queueOperation( new SimpleRemove( (E) element ) );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> coll) {
|
||||
read();
|
||||
|
|
|
@ -12,7 +12,9 @@ import org.hibernate.testing.orm.junit.SessionFactory;
|
|||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -35,12 +37,16 @@ public class CollectionSizeTest {
|
|||
emailAddresses.add( new EmailAddress( "test1@test.com" ) );
|
||||
emailAddresses.add( new EmailAddress( "test2@test.com" ) );
|
||||
emailAddresses.add( new EmailAddress( "test3@test.com" ) );
|
||||
List<EmailAddress> emailAddresses3 = new ArrayList<>();
|
||||
emailAddresses3.add( new EmailAddress( "test4@test.com" ) );
|
||||
emailAddresses3.add( new EmailAddress( "test5@test.com" ) );
|
||||
User user = new User();
|
||||
user.setName( "john" );
|
||||
Contact contact = new Contact();
|
||||
contact.setName( "John Doe" );
|
||||
contact.setEmailAddresses( emailAddresses );
|
||||
emailAddresses.forEach( address -> contact.getContactsByEmail().put(address, contact) );
|
||||
contact.setEmailAddresses3( emailAddresses3 );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
|
@ -53,15 +59,31 @@ public class CollectionSizeTest {
|
|||
scope.inTransaction(
|
||||
session -> {
|
||||
Contact cont = session.get(Contact.class, contact.getId());
|
||||
|
||||
Set<EmailAddress> addresses = cont.getEmailAddresses();
|
||||
assertEquals( Hibernate.size(addresses), 3 );
|
||||
assertTrue( Hibernate.contains( addresses, new EmailAddress( "test1@test.com" ) ) );
|
||||
assertFalse( Hibernate.contains( addresses, new EmailAddress( "test9@test.com" ) ) );
|
||||
assertFalse( Hibernate.isInitialized(addresses) );
|
||||
|
||||
Map<EmailAddress, Contact> contactsByEmail = cont.getContactsByEmail();
|
||||
assertEquals( cont, Hibernate.get(contactsByEmail, new EmailAddress( "test1@test.com" ) ) );
|
||||
assertNull( Hibernate.get(contactsByEmail, new EmailAddress( "test9@test.com" ) ) );
|
||||
assertFalse( Hibernate.isInitialized(contactsByEmail) );
|
||||
|
||||
Hibernate.remove( contactsByEmail, new EmailAddress( "test1@test.com" ) );
|
||||
assertFalse( Hibernate.isInitialized(contactsByEmail) );
|
||||
assertEquals( cont, Hibernate.get(contactsByEmail, new EmailAddress( "test1@test.com" ) ) );
|
||||
assertEquals( Hibernate.size( contactsByEmail.entrySet() ), 3 );
|
||||
|
||||
Hibernate.remove( addresses, new EmailAddress( "test1@test.com" ) );
|
||||
assertFalse( Hibernate.isInitialized(addresses) );
|
||||
assertEquals( Hibernate.size( addresses ), 3 );
|
||||
|
||||
List<EmailAddress> addresses3 = cont.getEmailAddresses3();
|
||||
Hibernate.remove( addresses3, new EmailAddress( "test4@test.com" ) );
|
||||
assertFalse( Hibernate.isInitialized( addresses3 ) );
|
||||
assertEquals( Hibernate.size(addresses3), 2 );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
package org.hibernate.orm.test.collection.basic;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import jakarta.persistence.Basic;
|
||||
|
@ -31,6 +33,8 @@ public class Contact implements Serializable {
|
|||
private String name;
|
||||
private Set<EmailAddress> emailAddresses = new HashSet<>();
|
||||
private Set<EmailAddress> emailAddresses2 = new HashSet<>();
|
||||
|
||||
private List<EmailAddress> emailAddresses3 = new ArrayList<>();
|
||||
private Map<EmailAddress,Contact> contactsByEmail = new HashMap<>();
|
||||
|
||||
@Id
|
||||
|
@ -52,6 +56,16 @@ public class Contact implements Serializable {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
@ElementCollection
|
||||
@CollectionTable(name = "user_email_addresses3", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"))
|
||||
public List<EmailAddress> getEmailAddresses3() {
|
||||
return emailAddresses3;
|
||||
}
|
||||
|
||||
public void setEmailAddresses3(List<EmailAddress> emailAddresses3) {
|
||||
this.emailAddresses3 = emailAddresses3;
|
||||
}
|
||||
|
||||
@ElementCollection
|
||||
@CollectionTable(name = "user_email_addresses2", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"))
|
||||
public Set<EmailAddress> getEmailAddresses2() {
|
||||
|
|
Loading…
Reference in New Issue