Initial work to re-organize the Collections chapter in the UserGuide;

Docs for @CollectionType, @CollectionClassificationType and @CollectionSemantics;
Some api/spi/internal work;
Migration Guide;
This commit is contained in:
Steve Ebersole 2022-01-05 16:24:11 -06:00
parent f7af0017f7
commit a71ba9e385
130 changed files with 2954 additions and 822 deletions

View File

@ -1,5 +1,5 @@
[[basic]] [[basic]]
=== Basic types === Basic values
:rootProjectDir: ../../../../../../.. :rootProjectDir: ../../../../../../..
:documentationProjectDir: {rootProjectDir}/documentation :documentationProjectDir: {rootProjectDir}/documentation
:coreProjectDir: {rootProjectDir}/hibernate-core :coreProjectDir: {rootProjectDir}/hibernate-core

View File

@ -1,5 +1,5 @@
[[embeddables]] [[embeddables]]
=== Embeddable types === Embeddable values
:rootProjectDir: ../../../../../../.. :rootProjectDir: ../../../../../../..
:sourcedir: ../../../../../test/java/org/hibernate/userguide/mapping/embeddable :sourcedir: ../../../../../test/java/org/hibernate/userguide/mapping/embeddable
:coreProjectDir: {rootProjectDir}/hibernate-core :coreProjectDir: {rootProjectDir}/hibernate-core

View File

@ -1,4 +1,4 @@
DELETE FROM Person_phones WHERE Person_id = 1 delete from Person_phones where Person_id=1
INSERT INTO Person_phones ( Person_id, phones ) INSERT INTO Person_phones ( Person_id, phones )
VALUES ( 1, '123-456-7890' ) VALUES ( 1, '123-456-7890' )

View File

@ -1,69 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.userguide.collections;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.annotations.JavaType;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.userguide.collections.type.CommaDelimitedStringsJavaTypeDescriptor;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
/**
* @author Vlad Mihalcea
*/
public class BasicTypeCollectionTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Person.class
};
}
@Test
public void testLifecycle() {
doInHibernate(this::sessionFactory, session -> {
Person person = new Person();
person.id = 1L;
session.persist(person);
//tag::collections-comma-delimited-collection-lifecycle-example[]
person.phones.add("027-123-4567");
person.phones.add("028-234-9876");
session.flush();
person.getPhones().remove(0);
//end::collections-comma-delimited-collection-lifecycle-example[]
});
}
//tag::collections-comma-delimited-collection-example[]
@Entity(name = "Person")
public static class Person {
@Id
private Long id;
@JavaType(CommaDelimitedStringsJavaTypeDescriptor.class)
@JdbcTypeCode(Types.VARCHAR)
private List<String> phones = new ArrayList<>();
public List<String> getPhones() {
return phones;
}
}
//end::collections-comma-delimited-collection-example[]
}

View File

@ -11,6 +11,7 @@ import java.util.List;
import jakarta.persistence.ElementCollection; import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import jakarta.persistence.OrderColumn;
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase; import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
@ -63,11 +64,11 @@ public class BasicTypeElementCollectionTest extends BaseEntityManagerFunctionalT
doInJPA(this::entityManagerFactory, entityManager -> { doInJPA(this::entityManagerFactory, entityManager -> {
Person person = entityManager.find(Person.class, 1L); Person person = entityManager.find(Person.class, 1L);
log.info("Clear element collection and add element"); log.info("Clear element collection and add element");
//tag::collections-value-type-collection-lifecycle-example[] //tag::ex-collection-elemental-lifecycle[]
person.getPhones().clear(); person.getPhones().clear();
person.getPhones().add("123-456-7890"); person.getPhones().add("123-456-7890");
person.getPhones().add("456-000-1234"); person.getPhones().add("456-000-1234");
//end::collections-value-type-collection-lifecycle-example[] //end::ex-collection-elemental-lifecycle[]
}); });
doInJPA(this::entityManagerFactory, entityManager -> { doInJPA(this::entityManagerFactory, entityManager -> {
Person person = entityManager.find(Person.class, 1L); Person person = entityManager.find(Person.class, 1L);
@ -78,7 +79,7 @@ public class BasicTypeElementCollectionTest extends BaseEntityManagerFunctionalT
}); });
} }
//tag::collections-collection-proxy-entity-example[] //tag::ex-collection-elemental-basic-model[]
@Entity(name = "Person") @Entity(name = "Person")
public static class Person { public static class Person {
@ -86,16 +87,17 @@ public class BasicTypeElementCollectionTest extends BaseEntityManagerFunctionalT
private Long id; private Long id;
@ElementCollection @ElementCollection
@OrderColumn( name = "_position")
private List<String> phones = new ArrayList<>(); private List<String> phones = new ArrayList<>();
//Getters and setters are omitted for brevity //Getters and setters are omitted for brevity
//end::collections-collection-proxy-entity-example[] //end::ex-collection-elemental-basic-model[]
public List<String> getPhones() { public List<String> getPhones() {
return phones; return phones;
} }
//tag::collections-collection-proxy-entity-example[] //tag::ex-collection-elemental-basic-model[]
} }
//end::collections-collection-proxy-entity-example[] //end::ex-collection-elemental-basic-model[]
} }

View File

@ -13,6 +13,7 @@ import jakarta.persistence.ElementCollection;
import jakarta.persistence.Embeddable; import jakarta.persistence.Embeddable;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import jakarta.persistence.Table;
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase; import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
@ -45,7 +46,8 @@ public class EmbeddableTypeElementCollectionTest extends BaseEntityManagerFuncti
}); });
} }
//tag::collections-embeddable-type-collection-lifecycle-entity-example[] @Table( name = "persons" )
//tag::ex-collection-elemental-basic-model[]
@Entity(name = "Person") @Entity(name = "Person")
public static class Person { public static class Person {
@ -57,12 +59,12 @@ public class EmbeddableTypeElementCollectionTest extends BaseEntityManagerFuncti
//Getters and setters are omitted for brevity //Getters and setters are omitted for brevity
//end::collections-embeddable-type-collection-lifecycle-entity-example[] //end::ex-collection-elemental-basic-model[]
public List<Phone> getPhones() { public List<Phone> getPhones() {
return phones; return phones;
} }
//tag::collections-embeddable-type-collection-lifecycle-entity-example[] //tag::ex-collection-elemental-basic-model[]
} }
@Embeddable @Embeddable
@ -75,7 +77,7 @@ public class EmbeddableTypeElementCollectionTest extends BaseEntityManagerFuncti
//Getters and setters are omitted for brevity //Getters and setters are omitted for brevity
//end::collections-embeddable-type-collection-lifecycle-entity-example[] //end::ex-collection-elemental-basic-model[]
public Phone() { public Phone() {
} }
@ -92,7 +94,7 @@ public class EmbeddableTypeElementCollectionTest extends BaseEntityManagerFuncti
public String getNumber() { public String getNumber() {
return number; return number;
} }
//tag::collections-embeddable-type-collection-lifecycle-entity-example[] //tag::ex-collection-elemental-basic-model[]
} }
//end::collections-embeddable-type-collection-lifecycle-entity-example[] //end::ex-collection-elemental-basic-model[]
} }

View File

@ -19,6 +19,7 @@ import jakarta.persistence.OneToMany;
import org.hibernate.annotations.CollectionType; import org.hibernate.annotations.CollectionType;
import org.hibernate.annotations.NaturalId; import org.hibernate.annotations.NaturalId;
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase; import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
import org.hibernate.userguide.collections.type.QueueType;
import org.junit.Test; import org.junit.Test;
@ -70,7 +71,7 @@ public class QueueTest extends BaseEntityManagerFunctionalTestCase {
private Long id; private Long id;
@OneToMany(cascade = CascadeType.ALL) @OneToMany(cascade = CascadeType.ALL)
@CollectionType(type = "org.hibernate.userguide.collections.type.QueueType") @CollectionType(type = QueueType.class )
private Collection<Phone> phones = new LinkedList<>(); private Collection<Phone> phones = new LinkedList<>();
//Constructors are omitted for brevity //Constructors are omitted for brevity

View File

@ -1,60 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.userguide.collections.type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.AbstractClassJavaTypeDescriptor;
import org.hibernate.type.descriptor.java.MutableMutabilityPlan;
/**
* @author Vlad Mihalcea
*/
//tag::collections-comma-delimited-collection-example[]
public class CommaDelimitedStringsJavaTypeDescriptor extends AbstractClassJavaTypeDescriptor<List> {
public static final String DELIMITER = ",";
public CommaDelimitedStringsJavaTypeDescriptor() {
super(
List.class,
new MutableMutabilityPlan<List>() {
@Override
protected List deepCopyNotNull(List value) {
return new ArrayList(value);
}
}
);
}
@Override
public String toString(List value) {
return ((List<String>) value).stream().collect(Collectors.joining(DELIMITER));
}
@Override
public List fromString(CharSequence string) {
List<String> values = new ArrayList<>();
Collections.addAll(values, string.toString().split(DELIMITER));
return values;
}
@Override
public <X> X unwrap(List value, Class<X> type, WrapperOptions options) {
return (X) toString(value);
}
@Override
public <X> List wrap(X value, WrapperOptions options) {
return fromString((CharSequence) value);
}
}
//end::collections-comma-delimited-collection-example[]

View File

@ -10,7 +10,7 @@ import java.util.List;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Queue; import java.util.Queue;
import org.hibernate.collection.internal.PersistentBag; import org.hibernate.collection.spi.PersistentBag;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
//tag::collections-custom-collection-mapping-example[] //tag::collections-custom-collection-mapping-example[]

View File

@ -22,12 +22,12 @@ import java.util.function.Supplier;
import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor; import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor;
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor; import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
import org.hibernate.collection.internal.PersistentBag; import org.hibernate.collection.spi.PersistentBag;
import org.hibernate.collection.internal.PersistentList; import org.hibernate.collection.spi.PersistentList;
import org.hibernate.collection.internal.PersistentMap; import org.hibernate.collection.spi.PersistentMap;
import org.hibernate.collection.internal.PersistentSet; import org.hibernate.collection.spi.PersistentSet;
import org.hibernate.collection.internal.PersistentSortedMap; import org.hibernate.collection.spi.PersistentSortedMap;
import org.hibernate.collection.internal.PersistentSortedSet; import org.hibernate.collection.spi.PersistentSortedSet;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.HibernateIterator; import org.hibernate.engine.HibernateIterator;
import org.hibernate.engine.jdbc.LobCreator; import org.hibernate.engine.jdbc.LobCreator;

View File

@ -7,7 +7,7 @@
package org.hibernate.action.internal; package org.hibernate.action.internal;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.collection.internal.AbstractPersistentCollection; import org.hibernate.collection.spi.AbstractPersistentCollection;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.CollectionEntry; import org.hibernate.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;

View File

@ -0,0 +1,27 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.annotations;
import java.lang.annotation.Retention;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Specifies a custom {@link org.hibernate.collection.spi.CollectionSemantics}
*
* @since 6.0
*
* @author Steve Ebersole
*/
@java.lang.annotation.Target({METHOD, FIELD, ANNOTATION_TYPE})
@Retention(RUNTIME)
public @interface CollectionSemantics {
Class<? extends org.hibernate.collection.spi.CollectionSemantics> value();
}

View File

@ -0,0 +1,45 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.annotations;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import org.hibernate.metamodel.CollectionClassification;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Allows to register a {@link org.hibernate.collection.spi.CollectionSemantics}
* to use as the default for the specified classification of collection.
*
* @see CollectionClassificationType
* @see CollectionSemantics
* @see org.hibernate.collection.spi.CollectionSemantics
*
* @since 6.0
*
* @author Steve Ebersole
*/
@java.lang.annotation.Target({METHOD, FIELD, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Repeatable( CollectionSemanticsRegistrations.class )
public @interface CollectionSemanticsRegistration {
/**
* The collection classification for which the supplied semantic applies
*/
CollectionClassification classification();
/**
* The semantic to apply. Will be applied to all collections of the given
* classification which do not define an explicit {@link org.hibernate.collection.spi.CollectionSemantics}
*/
Class<? extends org.hibernate.collection.spi.CollectionSemantics<?,?>> semantics();
}

View File

@ -0,0 +1,30 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.annotations;
import java.lang.annotation.Retention;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Repeatable container for {@link CollectionSemanticsRegistration}
*
* @since 6.0
*
* @author Steve Ebersole
*/
@java.lang.annotation.Target({METHOD, FIELD, ANNOTATION_TYPE})
@Retention(RUNTIME)
public @interface CollectionSemanticsRegistrations {
/**
* The individual CollectionSemanticsRegistrations
*/
CollectionSemanticsRegistration[] value();
}

View File

@ -8,32 +8,26 @@ package org.hibernate.annotations;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import org.hibernate.usertype.UserCollectionType;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
/** /**
* Names a custom collection type for a persistent collection. The collection can also name a @Type, which defines * Names a custom collection type for a persistent collection.
* the Hibernate Type of the collection elements.
*
* @see org.hibernate.type.CollectionType
* @see org.hibernate.usertype.UserCollectionType
* *
* @author Steve Ebersole * @author Steve Ebersole
*
* @deprecated Custom handling for "collection types" will be handled differently in 6.0
*/ */
@java.lang.annotation.Target({FIELD, METHOD}) @java.lang.annotation.Target({FIELD, METHOD, ANNOTATION_TYPE})
@Retention(RUNTIME) @Retention(RUNTIME)
@Deprecated
public @interface CollectionType { public @interface CollectionType {
/** /**
* Names the type. * Specifies the UserCollectionType to use when mapping the attribute
* * to which this annotation is attached.
* Could name the implementation class (an implementation of {@link org.hibernate.type.CollectionType} or
* {@link org.hibernate.usertype.UserCollectionType}).
*/ */
String type(); Class<? extends UserCollectionType> type();
/** /**
* Specifies the class to use the semantics of. * Specifies the class to use the semantics of.

View File

@ -27,7 +27,7 @@ public @interface CustomType {
/** /**
* The custom type implementor class * The custom type implementor class
*/ */
Class<? extends UserType> value(); Class<? extends UserType<?>> value();
/** /**
* Parameters to be injected into the custom type after * Parameters to be injected into the custom type after

View File

@ -6,7 +6,6 @@
*/ */
package org.hibernate.cfg; package org.hibernate.cfg;
import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
@ -15,6 +14,8 @@ import org.hibernate.boot.MetadataBuilder;
import org.hibernate.boot.registry.classloading.internal.TcclLookupPrecedence; import org.hibernate.boot.registry.classloading.internal.TcclLookupPrecedence;
import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.spi.TimestampsCacheFactory; import org.hibernate.cache.spi.TimestampsCacheFactory;
import org.hibernate.collection.spi.PersistentBag;
import org.hibernate.collection.spi.PersistentList;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver; import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
import org.hibernate.jpa.spi.JpaCompliance; import org.hibernate.jpa.spi.JpaCompliance;
import org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode; import org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode;
@ -2116,8 +2117,8 @@ public interface AvailableSettings {
/** /**
* Controls whether Hibernate should recognize what it considers a "bag" * Controls whether Hibernate should recognize what it considers a "bag"
* ({@link org.hibernate.collection.internal.PersistentBag}) as a List * ({@link PersistentBag}) as a List
* ({@link org.hibernate.collection.internal.PersistentList}) or as a bag. * ({@link PersistentList}) or as a bag.
* *
* If enabled, we will recognize it as a List where {@link jakarta.persistence.OrderColumn} * If enabled, we will recognize it as a List where {@link jakarta.persistence.OrderColumn}
* is just missing (and its defaults will apply). * is just missing (and its defaults will apply).
@ -2129,8 +2130,8 @@ public interface AvailableSettings {
/** /**
* Controls whether Hibernate should recognize what it considers a "bag" * Controls whether Hibernate should recognize what it considers a "bag"
* ({@link org.hibernate.collection.internal.PersistentBag}) as a List * ({@link PersistentBag}) as a List
* ({@link org.hibernate.collection.internal.PersistentList}) or as a bag. * ({@link PersistentList}) or as a bag.
* *
* If enabled, we will recognize it as a List where {@link jakarta.persistence.OrderColumn} * If enabled, we will recognize it as a List where {@link jakarta.persistence.OrderColumn}
* is just missing (and its defaults will apply). * is just missing (and its defaults will apply).

View File

@ -25,6 +25,7 @@ import org.hibernate.annotations.CollectionId;
import org.hibernate.annotations.CollectionIdJavaType; import org.hibernate.annotations.CollectionIdJavaType;
import org.hibernate.annotations.CollectionIdJdbcType; import org.hibernate.annotations.CollectionIdJdbcType;
import org.hibernate.annotations.CollectionIdJdbcTypeCode; import org.hibernate.annotations.CollectionIdJdbcTypeCode;
import org.hibernate.annotations.CollectionSemantics;
import org.hibernate.annotations.CollectionType; import org.hibernate.annotations.CollectionType;
import org.hibernate.annotations.Fetch; import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.Filter; import org.hibernate.annotations.Filter;
@ -103,6 +104,8 @@ import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table; import org.hibernate.mapping.Table;
import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.metamodel.EmbeddableInstantiator; import org.hibernate.metamodel.EmbeddableInstantiator;
import org.hibernate.resource.beans.spi.ManagedBean;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
@ -278,28 +281,48 @@ public abstract class CollectionBinder {
XProperty property, XProperty property,
boolean isHibernateExtensionMapping, boolean isHibernateExtensionMapping,
MetadataBuildingContext buildingContext) { MetadataBuildingContext buildingContext) {
final CollectionType typeAnnotation = property.getAnnotation( CollectionType.class ); final CollectionType typeAnnotation = HCANNHelper.findAnnotation( property, CollectionType.class );
final CollectionBinder binder; final CollectionBinder binder;
if ( typeAnnotation != null ) { if ( typeAnnotation != null ) {
binder = createBinderFromCustomTypeAnnotation( property, typeAnnotation, buildingContext ); binder = createBinderFromCustomTypeAnnotation( property, typeAnnotation, buildingContext );
} binder.explicitType = typeAnnotation.type().getName();
else {
binder = createBinderFromProperty( property, buildingContext );
}
binder.setIsHibernateExtensionMapping( isHibernateExtensionMapping );
if ( typeAnnotation != null ) {
binder.explicitType = typeAnnotation.type();
for ( Parameter param : typeAnnotation.parameters() ) { for ( Parameter param : typeAnnotation.parameters() ) {
binder.explicitTypeParameters.setProperty( param.name(), param.value() ); binder.explicitTypeParameters.setProperty( param.name(), param.value() );
} }
} }
else {
final CollectionSemantics customSemantics = property.getAnnotation( CollectionSemantics.class );
if ( customSemantics != null ) {
binder = createBinderFromCustomSemantics( customSemantics, property, buildingContext );
}
else {
binder = createBinderFromProperty( property, buildingContext );
}
}
binder.setIsHibernateExtensionMapping( isHibernateExtensionMapping );
return binder; return binder;
} }
private static CollectionBinder createBinderFromCustomSemantics(
CollectionSemantics customSemantics,
XProperty property,
MetadataBuildingContext buildingContext) {
final ManagedBeanRegistry beanRegistry = buildingContext.getBootstrapContext()
.getServiceRegistry()
.getService( ManagedBeanRegistry.class );
final ManagedBean<? extends org.hibernate.collection.spi.CollectionSemantics> semanticsBean = beanRegistry.getBean( customSemantics.value() );
final org.hibernate.collection.spi.CollectionSemantics semantics = semanticsBean.getBeanInstance();
return createBinder(
property,
semantics.getCollectionClassification(),
(type) -> semantics,
buildingContext
);
}
private static CollectionBinder createBinderFromProperty( private static CollectionBinder createBinderFromProperty(
XProperty property, XProperty property,
MetadataBuildingContext buildingContext) { MetadataBuildingContext buildingContext) {

View File

@ -13,6 +13,7 @@ import java.util.function.Consumer;
import org.hibernate.collection.spi.CollectionInitializerProducer; import org.hibernate.collection.spi.CollectionInitializerProducer;
import org.hibernate.collection.spi.CollectionSemantics; import org.hibernate.collection.spi.CollectionSemantics;
import org.hibernate.collection.spi.InitializerProducerBuilder; import org.hibernate.collection.spi.InitializerProducerBuilder;
import org.hibernate.collection.spi.PersistentArrayHolder;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.CollectionClassification;

View File

@ -8,6 +8,8 @@ package org.hibernate.collection.internal;
import java.util.Collection; import java.util.Collection;
import org.hibernate.collection.spi.AbstractBagSemantics;
import org.hibernate.collection.spi.PersistentBag;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.CollectionClassification;

View File

@ -8,7 +8,9 @@ package org.hibernate.collection.internal;
import java.util.Collection; import java.util.Collection;
import org.hibernate.collection.spi.AbstractBagSemantics;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.collection.spi.PersistentIdentifierBag;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;

View File

@ -14,6 +14,7 @@ import org.hibernate.collection.spi.CollectionInitializerProducer;
import org.hibernate.collection.spi.CollectionSemantics; import org.hibernate.collection.spi.CollectionSemantics;
import org.hibernate.collection.spi.InitializerProducerBuilder; import org.hibernate.collection.spi.InitializerProducerBuilder;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.collection.spi.PersistentList;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.CollectionClassification;

View File

@ -8,7 +8,9 @@ package org.hibernate.collection.internal;
import java.util.Map; import java.util.Map;
import org.hibernate.collection.spi.AbstractMapSemantics;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.collection.spi.PersistentMap;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.CollectionClassification;

View File

@ -8,9 +8,10 @@ package org.hibernate.collection.internal;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map;
import org.hibernate.collection.spi.AbstractMapSemantics;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.collection.spi.PersistentMap;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.CollectionClassification;

View File

@ -6,7 +6,9 @@
*/ */
package org.hibernate.collection.internal; package org.hibernate.collection.internal;
import org.hibernate.collection.spi.AbstractSetSemantics;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.collection.spi.PersistentSet;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.CollectionClassification;

View File

@ -9,6 +9,8 @@ package org.hibernate.collection.internal;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.hibernate.collection.spi.AbstractSetSemantics;
import org.hibernate.collection.spi.PersistentSet;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.CollectionClassification;

View File

@ -10,7 +10,9 @@ import java.util.Comparator;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
import org.hibernate.collection.spi.AbstractMapSemantics;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.collection.spi.PersistentSortedMap;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;

View File

@ -11,7 +11,9 @@ import java.util.Iterator;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import org.hibernate.collection.spi.AbstractSetSemantics;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.collection.spi.PersistentSortedSet;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later * License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/ */
package org.hibernate.collection.internal; package org.hibernate.collection.spi;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later * License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/ */
package org.hibernate.collection.internal; package org.hibernate.collection.spi;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;

View File

@ -1,10 +1,10 @@
/* /*
* Hibernate, Relational Persistence for Idiomatic Java * Hibernate, Relational Persistence for Idiomatic Java
* *
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/ */
package org.hibernate.collection.internal; package org.hibernate.collection.spi;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
@ -21,7 +21,6 @@ import org.hibernate.AssertionFailure;
import org.hibernate.FlushMode; import org.hibernate.FlushMode;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.LazyInitializationException; import org.hibernate.LazyInitializationException;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.internal.ForeignKeys; import org.hibernate.engine.internal.ForeignKeys;
import org.hibernate.engine.spi.CollectionEntry; import org.hibernate.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityEntry;

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later * License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/ */
package org.hibernate.collection.internal; package org.hibernate.collection.spi;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set; import java.util.Set;

View File

@ -8,6 +8,7 @@ package org.hibernate.collection.spi;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.hibernate.Incubating;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
@ -23,6 +24,7 @@ import org.hibernate.sql.results.graph.Initializer;
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@Incubating
@FunctionalInterface @FunctionalInterface
public interface CollectionInitializerProducer { public interface CollectionInitializerProducer {
/** /**

View File

@ -23,5 +23,5 @@ import org.hibernate.mapping.Collection;
@Incubating @Incubating
public interface CollectionSemanticsResolver { public interface CollectionSemanticsResolver {
// really need some form of access to the attribute site // really need some form of access to the attribute site
CollectionSemantics resolveRepresentation(Collection bootDescriptor); <CE,E> CollectionSemantics<CE,E> resolveRepresentation(Collection bootDescriptor);
} }

View File

@ -6,6 +6,7 @@
*/ */
package org.hibernate.collection.spi; package org.hibernate.collection.spi;
import org.hibernate.Incubating;
import org.hibernate.engine.FetchTiming; import org.hibernate.engine.FetchTiming;
import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.metamodel.mapping.CollectionPart; import org.hibernate.metamodel.mapping.CollectionPart;
@ -23,6 +24,7 @@ import org.hibernate.sql.results.graph.collection.internal.SetInitializerProduce
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@Incubating
public class InitializerProducerBuilder { public class InitializerProducerBuilder {
public static CollectionInitializerProducer createInitializerProducer( public static CollectionInitializerProducer createInitializerProducer(
NavigablePath navigablePath, NavigablePath navigablePath,

View File

@ -1,10 +1,10 @@
/* /*
* Hibernate, Relational Persistence for Idiomatic Java * Hibernate, Relational Persistence for Idiomatic Java
* *
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/ */
package org.hibernate.collection.internal; package org.hibernate.collection.spi;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Array; import java.lang.reflect.Array;
@ -15,27 +15,29 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.Incubating;
import org.hibernate.collection.spi.AbstractPersistentCollection;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.type.Type; import org.hibernate.type.Type;
import org.jboss.logging.Logger;
/** /**
* A persistent wrapper for an array. Lazy initialization * A persistent wrapper for an array. Lazy initialization
* is NOT supported. Use of Hibernate arrays is not really * is NOT supported. Use of Hibernate arrays is not really
* recommended. * recommended.
* *
* @apiNote Incubating in terms of making this non-internal. These contracts
* will be getting cleaned up in following releases.
*
* @author Gavin King * @author Gavin King
*/ */
@Incubating
public class PersistentArrayHolder<E> extends AbstractPersistentCollection<E> { public class PersistentArrayHolder<E> extends AbstractPersistentCollection<E> {
private static final CoreMessageLogger LOG = Logger.getMessageLogger( private static final CoreMessageLogger LOG = CoreLogging.messageLogger( PersistentArrayHolder.class );
CoreMessageLogger.class,
PersistentArrayHolder.class.getName()
);
protected Object array; protected Object array;

View File

@ -1,10 +1,10 @@
/* /*
* Hibernate, Relational Persistence for Idiomatic Java * Hibernate, Relational Persistence for Idiomatic Java
* *
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/ */
package org.hibernate.collection.internal; package org.hibernate.collection.spi;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
@ -17,7 +17,7 @@ import java.util.ListIterator;
import java.util.Map; import java.util.Map;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.collection.spi.CollectionSemantics; import org.hibernate.Incubating;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping;
@ -30,8 +30,12 @@ import org.hibernate.type.Type;
* Most developers seem to use {@code List}s to represent bag semantics, * Most developers seem to use {@code List}s to represent bag semantics,
* so Hibernate follows this practice. * so Hibernate follows this practice.
* *
* @apiNote Incubating in terms of making this non-internal. These contracts
* will be getting cleaned up in following releases.
*
* @author Gavin King * @author Gavin King
*/ */
@Incubating
public class PersistentBag<E> extends AbstractPersistentCollection<E> implements List<E> { public class PersistentBag<E> extends AbstractPersistentCollection<E> implements List<E> {
protected List<E> bag; protected List<E> bag;

View File

@ -12,6 +12,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.Incubating;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;
@ -44,6 +45,7 @@ import org.hibernate.type.Type;
* *
* @author Gavin King * @author Gavin King
*/ */
@Incubating
public interface PersistentCollection<E> { public interface PersistentCollection<E> {
/** /**
* Get the owning entity. Note that the owner is only * Get the owning entity. Note that the owner is only

View File

@ -1,10 +1,10 @@
/* /*
* Hibernate, Relational Persistence for Idiomatic Java * Hibernate, Relational Persistence for Idiomatic Java
* *
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/ */
package org.hibernate.collection.internal; package org.hibernate.collection.spi;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
@ -16,6 +16,7 @@ import java.util.ListIterator;
import java.util.Map; import java.util.Map;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.Incubating;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;
@ -33,8 +34,12 @@ import org.hibernate.type.Type;
* {@code IdentifierBag}s may not be used for a many-to-one association. * {@code IdentifierBag}s may not be used for a many-to-one association.
* Furthermore, there is no reason to use {@code inverse="true"}. * Furthermore, there is no reason to use {@code inverse="true"}.
* *
* @apiNote Incubating in terms of making this non-internal. These contracts
* will be getting cleaned up in following releases.
*
* @author Gavin King * @author Gavin King
*/ */
@Incubating
public class PersistentIdentifierBag<E> extends AbstractPersistentCollection<E> implements List<E> { public class PersistentIdentifierBag<E> extends AbstractPersistentCollection<E> implements List<E> {
protected List<E> values; protected List<E> values;
protected Map<Integer, Object> identifiers; protected Map<Integer, Object> identifiers;

View File

@ -1,10 +1,10 @@
/* /*
* Hibernate, Relational Persistence for Idiomatic Java * Hibernate, Relational Persistence for Idiomatic Java
* *
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/ */
package org.hibernate.collection.internal; package org.hibernate.collection.spi;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
@ -14,6 +14,7 @@ import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.Incubating;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping;
@ -24,9 +25,12 @@ import org.hibernate.type.Type;
* A persistent wrapper for a {@code java.util.List}. Underlying * A persistent wrapper for a {@code java.util.List}. Underlying
* collection is an {@code ArrayList}. * collection is an {@code ArrayList}.
* *
* @see ArrayList * @apiNote Incubating in terms of making this non-internal. These contracts
* will be getting cleaned up in following releases.
*
* @author Gavin King * @author Gavin King
*/ */
@Incubating
public class PersistentList<E> extends AbstractPersistentCollection<E> implements List<E> { public class PersistentList<E> extends AbstractPersistentCollection<E> implements List<E> {
protected List<E> list; protected List<E> list;
@ -81,6 +85,10 @@ public class PersistentList<E> extends AbstractPersistentCollection<E> implement
this( (SharedSessionContractImplementor) session, list ); this( (SharedSessionContractImplementor) session, list );
} }
protected List<E> getRawList() {
return list;
}
@Override @Override
public Serializable getSnapshot(CollectionPersister persister) throws HibernateException { public Serializable getSnapshot(CollectionPersister persister) throws HibernateException {
final ArrayList<Object> clonedList = new ArrayList<>( list.size() ); final ArrayList<Object> clonedList = new ArrayList<>( list.size() );
@ -511,7 +519,7 @@ public class PersistentList<E> extends AbstractPersistentCollection<E> implement
} }
} }
final class SimpleAdd extends AbstractValueDelayedOperation { protected final class SimpleAdd extends AbstractValueDelayedOperation {
public SimpleAdd(E addedValue) { public SimpleAdd(E addedValue) {
super( addedValue, null ); super( addedValue, null );

View File

@ -1,10 +1,10 @@
/* /*
* Hibernate, Relational Persistence for Idiomatic Java * Hibernate, Relational Persistence for Idiomatic Java
* *
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/ */
package org.hibernate.collection.internal; package org.hibernate.collection.spi;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
@ -16,6 +16,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.Incubating;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;
@ -28,9 +29,12 @@ import org.hibernate.type.Type;
* A persistent wrapper for a {@code java.util.Map}. Underlying collection * A persistent wrapper for a {@code java.util.Map}. Underlying collection
* is a {@code HashMap}. * is a {@code HashMap}.
* *
* @see HashMap * @apiNote Incubating in terms of making this non-internal. These contracts
* will be getting cleaned up in following releases.
*
* @author Gavin King * @author Gavin King
*/ */
@Incubating
public class PersistentMap<K,E> extends AbstractPersistentCollection<E> implements Map<K,E> { public class PersistentMap<K,E> extends AbstractPersistentCollection<E> implements Map<K,E> {
protected Map<K,E> map; protected Map<K,E> map;

View File

@ -1,10 +1,10 @@
/* /*
* Hibernate, Relational Persistence for Idiomatic Java * Hibernate, Relational Persistence for Idiomatic Java
* *
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/ */
package org.hibernate.collection.internal; package org.hibernate.collection.spi;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
@ -15,6 +15,8 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.Incubating;
import org.hibernate.collection.spi.AbstractPersistentCollection;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;
@ -27,9 +29,12 @@ import org.hibernate.type.Type;
* A persistent wrapper for a {@code java.util.Set}. The underlying * A persistent wrapper for a {@code java.util.Set}. The underlying
* collection is a {@code HashSet}. * collection is a {@code HashSet}.
* *
* @see java.util.HashSet * @apiNote Incubating in terms of making this non-internal. These contracts
* will be getting cleaned up in following releases.
*
* @author Gavin King * @author Gavin King
*/ */
@Incubating
public class PersistentSet<E> extends AbstractPersistentCollection<E> implements Set<E> { public class PersistentSet<E> extends AbstractPersistentCollection<E> implements Set<E> {
protected Set<E> set; protected Set<E> set;

View File

@ -1,10 +1,10 @@
/* /*
* Hibernate, Relational Persistence for Idiomatic Java * Hibernate, Relational Persistence for Idiomatic Java
* *
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/ */
package org.hibernate.collection.internal; package org.hibernate.collection.spi;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collection; import java.util.Collection;
@ -15,6 +15,7 @@ import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.Incubating;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.BasicCollectionPersister; import org.hibernate.persister.collection.BasicCollectionPersister;
@ -23,9 +24,12 @@ import org.hibernate.persister.collection.BasicCollectionPersister;
* A persistent wrapper for a {@code java.util.SortedMap}. Underlying * A persistent wrapper for a {@code java.util.SortedMap}. Underlying
* collection is a {@code TreeMap}. * collection is a {@code TreeMap}.
* *
* @see TreeMap * @apiNote Incubating in terms of making this non-internal. These contracts
* will be getting cleaned up in following releases.
*
* @author <a href="mailto:doug.currie@alum.mit.edu">e</a> * @author <a href="mailto:doug.currie@alum.mit.edu">e</a>
*/ */
@Incubating
public class PersistentSortedMap<K,E> extends PersistentMap<K,E> implements SortedMap<K,E> { public class PersistentSortedMap<K,E> extends PersistentMap<K,E> implements SortedMap<K,E> {
protected Comparator<? super K> comparator; protected Comparator<? super K> comparator;

View File

@ -1,10 +1,10 @@
/* /*
* Hibernate, Relational Persistence for Idiomatic Java * Hibernate, Relational Persistence for Idiomatic Java
* *
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/ */
package org.hibernate.collection.internal; package org.hibernate.collection.spi;
import java.io.Serializable; import java.io.Serializable;
import java.util.Comparator; import java.util.Comparator;
@ -12,6 +12,7 @@ import java.util.SortedSet;
import java.util.TreeMap; import java.util.TreeMap;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.Incubating;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.BasicCollectionPersister; import org.hibernate.persister.collection.BasicCollectionPersister;
@ -20,9 +21,12 @@ import org.hibernate.persister.collection.BasicCollectionPersister;
* A persistent wrapper for a {@code java.util.SortedSet}. Underlying * A persistent wrapper for a {@code java.util.SortedSet}. Underlying
* collection is a {@code TreeSet}. * collection is a {@code TreeSet}.
* *
* @see java.util.TreeSet * @apiNote Incubating in terms of making this non-internal. These contracts
* will be getting cleaned up in following releases.
*
* @author <a href="mailto:doug.currie@alum.mit.edu">e</a> * @author <a href="mailto:doug.currie@alum.mit.edu">e</a>
*/ */
@Incubating
public class PersistentSortedSet<E> extends PersistentSet<E> implements SortedSet<E> { public class PersistentSortedSet<E> extends PersistentSet<E> implements SortedSet<E> {
protected Comparator<? super E> comparator; protected Comparator<? super E> comparator;

View File

@ -15,7 +15,7 @@ import java.util.Collection;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.collection.internal.AbstractPersistentCollection; import org.hibernate.collection.spi.AbstractPersistentCollection;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;

View File

@ -43,8 +43,8 @@ public interface JpaCompliance {
* JPA does not have. * JPA does not have.
* *
* If enabled, Hibernate will recognize this condition as defining * If enabled, Hibernate will recognize this condition as defining
* a {@link org.hibernate.collection.internal.PersistentList}, otherwise * a {@link org.hibernate.collection.spi.PersistentList}, otherwise
* Hibernate will treat is as a {@link org.hibernate.collection.internal.PersistentBag} * Hibernate will treat is as a {@link org.hibernate.collection.spi.PersistentBag}
* *
* @return {@code true} indicates to behave in the spec-defined way, interpreting the * @return {@code true} indicates to behave in the spec-defined way, interpreting the
* mapping as a "list", rather than a "bag" * mapping as a "list", rather than a "bag"

View File

@ -8,7 +8,7 @@ package org.hibernate.sql.results.graph.collection.internal;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.hibernate.collection.internal.PersistentArrayHolder; import org.hibernate.collection.spi.PersistentArrayHolder;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.sql.results.graph.DomainResultAssembler; import org.hibernate.sql.results.graph.DomainResultAssembler;

View File

@ -9,7 +9,7 @@ package org.hibernate.sql.results.graph.collection.internal;
import java.util.List; import java.util.List;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.collection.internal.PersistentArrayHolder; import org.hibernate.collection.spi.PersistentArrayHolder;
import org.hibernate.engine.spi.CollectionKey; import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.internal.log.LoggingHelper; import org.hibernate.internal.log.LoggingHelper;
import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping;

View File

@ -9,8 +9,8 @@ package org.hibernate.sql.results.graph.collection.internal;
import java.util.List; import java.util.List;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.collection.internal.PersistentBag; import org.hibernate.collection.spi.PersistentBag;
import org.hibernate.collection.internal.PersistentIdentifierBag; import org.hibernate.collection.spi.PersistentIdentifierBag;
import org.hibernate.engine.spi.CollectionKey; import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.internal.log.LoggingHelper; import org.hibernate.internal.log.LoggingHelper;
import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping;

View File

@ -9,7 +9,7 @@ package org.hibernate.sql.results.graph.collection.internal;
import java.util.List; import java.util.List;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.collection.internal.PersistentList; import org.hibernate.collection.spi.PersistentList;
import org.hibernate.engine.spi.CollectionKey; import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.internal.log.LoggingHelper; import org.hibernate.internal.log.LoggingHelper;
import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping;

View File

@ -9,7 +9,7 @@ package org.hibernate.sql.results.graph.collection.internal;
import java.util.List; import java.util.List;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.collection.internal.PersistentMap; import org.hibernate.collection.spi.PersistentMap;
import org.hibernate.engine.spi.CollectionKey; import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.internal.log.LoggingHelper; import org.hibernate.internal.log.LoggingHelper;
import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping;

View File

@ -9,7 +9,7 @@ package org.hibernate.sql.results.graph.collection.internal;
import java.util.List; import java.util.List;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.collection.internal.PersistentSet; import org.hibernate.collection.spi.PersistentSet;
import org.hibernate.engine.spi.CollectionKey; import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.internal.log.LoggingHelper; import org.hibernate.internal.log.LoggingHelper;
import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping;

View File

@ -14,11 +14,10 @@ import java.util.function.Supplier;
import org.hibernate.CacheMode; import org.hibernate.CacheMode;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.cache.spi.access.CollectionDataAccess;
import org.hibernate.cache.spi.entry.CollectionCacheEntry;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.LockOptions; import org.hibernate.LockOptions;
import org.hibernate.collection.internal.PersistentArrayHolder; import org.hibernate.cache.spi.access.CollectionDataAccess;
import org.hibernate.cache.spi.entry.CollectionCacheEntry;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.BatchFetchQueue; import org.hibernate.engine.spi.BatchFetchQueue;
import org.hibernate.engine.spi.CollectionEntry; import org.hibernate.engine.spi.CollectionEntry;

View File

@ -16,7 +16,7 @@ import java.util.Map;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer; import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer;
import org.hibernate.collection.internal.PersistentArrayHolder; import org.hibernate.collection.spi.PersistentArrayHolder;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;

View File

@ -10,7 +10,7 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.collection.internal.PersistentBag; import org.hibernate.collection.spi.PersistentBag;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;

View File

@ -23,7 +23,7 @@ import org.hibernate.HibernateException;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer; import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer;
import org.hibernate.collection.internal.AbstractPersistentCollection; import org.hibernate.collection.spi.AbstractPersistentCollection;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.jdbc.Size; import org.hibernate.engine.jdbc.Size;
import org.hibernate.engine.spi.CollectionEntry; import org.hibernate.engine.spi.CollectionEntry;

View File

@ -92,7 +92,7 @@ public class CustomType<J>
} }
// create a JdbcType adapter that uses the UserType binder/extract handling // create a JdbcType adapter that uses the UserType binder/extract handling
this.jdbcType = new UserTypeSqlTypeAdapter<>( userType, mappedJavaTypeDescriptor ); this.jdbcType = new UserTypeSqlTypeAdapter<>( userType, mappedJavaTypeDescriptor , typeConfiguration);
this.valueExtractor = jdbcType.getExtractor( mappedJavaTypeDescriptor ); this.valueExtractor = jdbcType.getExtractor( mappedJavaTypeDescriptor );
this.valueBinder = jdbcType.getBinder( mappedJavaTypeDescriptor ); this.valueBinder = jdbcType.getBinder( mappedJavaTypeDescriptor );

View File

@ -9,7 +9,7 @@ package org.hibernate.type;
import java.util.ArrayList; import java.util.ArrayList;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.collection.internal.PersistentIdentifierBag; import org.hibernate.collection.spi.PersistentIdentifierBag;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;

View File

@ -9,7 +9,7 @@ package org.hibernate.type;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.hibernate.collection.internal.PersistentList; import org.hibernate.collection.spi.PersistentList;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;

View File

@ -11,7 +11,7 @@ import java.util.Iterator;
import java.util.Map; import java.util.Map;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.collection.internal.PersistentMap; import org.hibernate.collection.spi.PersistentMap;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;

View File

@ -6,7 +6,7 @@
*/ */
package org.hibernate.type; package org.hibernate.type;
import org.hibernate.collection.internal.PersistentSet; import org.hibernate.collection.spi.PersistentSet;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;

View File

@ -9,7 +9,7 @@ package org.hibernate.type;
import java.util.Comparator; import java.util.Comparator;
import java.util.TreeMap; import java.util.TreeMap;
import org.hibernate.collection.internal.PersistentSortedMap; import org.hibernate.collection.spi.PersistentSortedMap;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;

View File

@ -9,7 +9,7 @@ package org.hibernate.type;
import java.util.Comparator; import java.util.Comparator;
import java.util.TreeSet; import java.util.TreeSet;
import org.hibernate.collection.internal.PersistentSortedSet; import org.hibernate.collection.spi.PersistentSortedSet;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;

View File

@ -16,4 +16,46 @@ public interface JdbcBindingLogging {
boolean TRACE_ENABLED = LOGGER.isTraceEnabled(); boolean TRACE_ENABLED = LOGGER.isTraceEnabled();
boolean DEBUG_ENABLED = LOGGER.isDebugEnabled(); boolean DEBUG_ENABLED = LOGGER.isDebugEnabled();
static void logBinding(int jdbcPosition, int typeCode, Object value) {
assert TRACE_ENABLED;
LOGGER.tracef(
"binding parameter [%s] as [%s] - [%s]",
jdbcPosition,
JdbcTypeNameMapper.getTypeName( typeCode ),
value
);
}
static void logNullBinding(int jdbcPosition, int typeCode) {
assert TRACE_ENABLED;
LOGGER.tracef(
"binding parameter [%s] as [%s] - [null]",
jdbcPosition,
JdbcTypeNameMapper.getTypeName( typeCode )
);
}
static void logBinding(String callableParameterName, int typeCode, Object value) {
assert TRACE_ENABLED;
LOGGER.tracef(
"binding parameter [%s] as [%s] - [%s]",
callableParameterName,
JdbcTypeNameMapper.getTypeName( typeCode ),
value
);
}
static void logNullBinding(String callableParameterName, int typeCode) {
assert TRACE_ENABLED;
LOGGER.tracef(
"binding parameter [%s] as [%s] - [null]",
callableParameterName,
JdbcTypeNameMapper.getTypeName( typeCode )
);
}
} }

View File

@ -16,4 +16,46 @@ public interface JdbcExtractingLogging {
boolean TRACE_ENABLED = LOGGER.isTraceEnabled(); boolean TRACE_ENABLED = LOGGER.isTraceEnabled();
boolean DEBUG_ENABLED = LOGGER.isDebugEnabled(); boolean DEBUG_ENABLED = LOGGER.isDebugEnabled();
static void logExtracted(int jdbcPosition, int typeCode, Object value) {
assert TRACE_ENABLED;
JdbcExtractingLogging.LOGGER.tracef(
"extracted value ([%s] : [%s]) - [%s]",
jdbcPosition,
JdbcTypeNameMapper.getTypeName( typeCode ),
value
);
}
static void logNullExtracted(int jdbcPosition, int typeCode) {
assert TRACE_ENABLED;
JdbcExtractingLogging.LOGGER.tracef(
"extracted value ([%s] : [%s]) - [null]",
jdbcPosition,
JdbcTypeNameMapper.getTypeName( typeCode )
);
}
static void logExtracted(String callableParamName, int typeCode, Object value) {
assert TRACE_ENABLED;
JdbcExtractingLogging.LOGGER.tracef(
"extracted value ([%s] : [%s]) - [%s]",
callableParamName,
JdbcTypeNameMapper.getTypeName( typeCode ),
value
);
}
static void logNullExtracted(String callableParamName, int typeCode) {
assert TRACE_ENABLED;
JdbcExtractingLogging.LOGGER.tracef(
"extracted value ([%s] : [%s]) - [null]",
callableParamName,
JdbcTypeNameMapper.getTypeName( typeCode )
);
}
} }

View File

@ -12,7 +12,6 @@ import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import org.hibernate.type.descriptor.JdbcBindingLogging; import org.hibernate.type.descriptor.JdbcBindingLogging;
import org.hibernate.type.descriptor.JdbcTypeNameMapper;
import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
@ -46,25 +45,19 @@ public abstract class BasicBinder<J> implements ValueBinder<J>, Serializable {
public final void bind(PreparedStatement st, J value, int index, WrapperOptions options) throws SQLException { public final void bind(PreparedStatement st, J value, int index, WrapperOptions options) throws SQLException {
if ( value == null ) { if ( value == null ) {
if ( JdbcBindingLogging.TRACE_ENABLED ) { if ( JdbcBindingLogging.TRACE_ENABLED ) {
JdbcBindingLogging.LOGGER.trace( JdbcBindingLogging.logNullBinding(
String.format(
NULL_BIND_MSG_TEMPLATE,
index, index,
JdbcTypeNameMapper.getTypeName( getJdbcTypeDescriptor().getDefaultSqlTypeCode() ) jdbcType.getDefaultSqlTypeCode()
)
); );
} }
doBindNull( st, index, options ); doBindNull( st, index, options );
} }
else { else {
if ( JdbcBindingLogging.TRACE_ENABLED ) { if ( JdbcBindingLogging.TRACE_ENABLED ) {
JdbcBindingLogging.LOGGER.trace( JdbcBindingLogging.logBinding(
String.format(
BIND_MSG_TEMPLATE,
index, index,
JdbcTypeNameMapper.getTypeName( jdbcType.getDefaultSqlTypeCode() ), jdbcType.getDefaultSqlTypeCode(),
getJavaTypeDescriptor().extractLoggableRepresentation( value ) getJavaTypeDescriptor().extractLoggableRepresentation( value )
)
); );
} }
doBind( st, value, index, options ); doBind( st, value, index, options );
@ -75,25 +68,19 @@ public abstract class BasicBinder<J> implements ValueBinder<J>, Serializable {
public final void bind(CallableStatement st, J value, String name, WrapperOptions options) throws SQLException { public final void bind(CallableStatement st, J value, String name, WrapperOptions options) throws SQLException {
if ( value == null ) { if ( value == null ) {
if ( JdbcBindingLogging.TRACE_ENABLED ) { if ( JdbcBindingLogging.TRACE_ENABLED ) {
JdbcBindingLogging.LOGGER.trace( JdbcBindingLogging.logNullBinding(
String.format(
NULL_BIND_MSG_TEMPLATE,
name, name,
JdbcTypeNameMapper.getTypeName( getJdbcTypeDescriptor().getDefaultSqlTypeCode() ) jdbcType.getDefaultSqlTypeCode()
)
); );
} }
doBindNull( st, name, options ); doBindNull( st, name, options );
} }
else { else {
if ( JdbcBindingLogging.TRACE_ENABLED ) { if ( JdbcBindingLogging.TRACE_ENABLED ) {
JdbcBindingLogging.LOGGER.trace( JdbcBindingLogging.logBinding(
String.format(
BIND_MSG_TEMPLATE,
name, name,
JdbcTypeNameMapper.getTypeName( jdbcType.getDefaultSqlTypeCode() ), jdbcType.getDefaultSqlTypeCode(),
getJavaTypeDescriptor().extractLoggableRepresentation( value ) getJavaTypeDescriptor().extractLoggableRepresentation( value )
)
); );
} }
doBind( st, value, name, options ); doBind( st, value, name, options );

View File

@ -44,20 +44,18 @@ public abstract class BasicExtractor<J> implements ValueExtractor<J>, Serializab
final J value = doExtract( rs, paramIndex, options ); final J value = doExtract( rs, paramIndex, options );
if ( value == null || rs.wasNull() ) { if ( value == null || rs.wasNull() ) {
if ( JdbcExtractingLogging.TRACE_ENABLED ) { if ( JdbcExtractingLogging.TRACE_ENABLED ) {
JdbcExtractingLogging.LOGGER.tracef( JdbcExtractingLogging.logNullExtracted(
"extracted value ([%s] : [%s]) - [null]",
paramIndex, paramIndex,
JdbcTypeNameMapper.getTypeName( getJdbcTypeDescriptor().getDefaultSqlTypeCode() ) getJdbcTypeDescriptor().getDefaultSqlTypeCode()
); );
} }
return null; return null;
} }
else { else {
if ( JdbcExtractingLogging.TRACE_ENABLED ) { if ( JdbcExtractingLogging.TRACE_ENABLED ) {
JdbcExtractingLogging.LOGGER.tracef( JdbcExtractingLogging.logExtracted(
"extracted value ([%s] : [%s]) - [%s]",
paramIndex, paramIndex,
JdbcTypeNameMapper.getTypeName( getJdbcTypeDescriptor().getDefaultSqlTypeCode() ), getJdbcTypeDescriptor().getDefaultSqlTypeCode(),
getJavaTypeDescriptor().extractLoggableRepresentation( value ) getJavaTypeDescriptor().extractLoggableRepresentation( value )
); );
} }

View File

@ -13,6 +13,8 @@ import java.sql.SQLException;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.type.ProcedureParameterExtractionAware; import org.hibernate.type.ProcedureParameterExtractionAware;
import org.hibernate.type.descriptor.JdbcBindingLogging;
import org.hibernate.type.descriptor.JdbcExtractingLogging;
import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor; import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.WrapperOptions;
@ -36,12 +38,12 @@ public class UserTypeSqlTypeAdapter<J> implements JdbcType {
private final ValueExtractor<J> valueExtractor; private final ValueExtractor<J> valueExtractor;
private final ValueBinder<J> valueBinder; private final ValueBinder<J> valueBinder;
public UserTypeSqlTypeAdapter(UserType<J> userType, BasicJavaType<J> jtd) { public UserTypeSqlTypeAdapter(UserType<J> userType, BasicJavaType<J> jtd, TypeConfiguration typeConfiguration) {
this.userType = userType; this.userType = userType;
this.jtd = jtd; this.jtd = jtd;
this.valueExtractor = new ValueExtractorImpl<>( userType ); this.valueExtractor = new ValueExtractorImpl<>( userType, jtd );
this.valueBinder = new ValueBinderImpl<>( userType ); this.valueBinder = new ValueBinderImpl<>( userType, typeConfiguration );
} }
@Override @Override
@ -94,21 +96,27 @@ public class UserTypeSqlTypeAdapter<J> implements JdbcType {
private static class ValueExtractorImpl<J> implements ValueExtractor<J> { private static class ValueExtractorImpl<J> implements ValueExtractor<J> {
private final UserType<J> userType; private final UserType<J> userType;
private final JavaType<J> javaType;
public ValueExtractorImpl(UserType<J> userType) { public ValueExtractorImpl(UserType<J> userType, BasicJavaType<J> javaType) {
this.userType = userType; this.userType = userType;
this.javaType = javaType;
} }
@Override @Override
public J extract(ResultSet rs, int paramIndex, WrapperOptions options) throws SQLException { public J extract(ResultSet rs, int paramIndex, WrapperOptions options) throws SQLException {
return userType.nullSafeGet( rs, paramIndex, options.getSession(), null ); final J extracted = userType.nullSafeGet( rs, paramIndex, options.getSession(), null );
logExtracted( paramIndex, extracted );
return extracted;
} }
@Override @Override
public J extract(CallableStatement statement, int paramIndex, WrapperOptions options) throws SQLException { public J extract(CallableStatement statement, int paramIndex, WrapperOptions options) throws SQLException {
if ( userType instanceof ProcedureParameterExtractionAware ) { if ( userType instanceof ProcedureParameterExtractionAware ) {
//noinspection unchecked //noinspection unchecked
return ( (ProcedureParameterExtractionAware<J>) userType ).extract( statement, paramIndex, options.getSession() ); final J extracted = ( (ProcedureParameterExtractionAware<J>) userType ).extract( statement, paramIndex, options.getSession() );
logExtracted( paramIndex, extracted );
return extracted;
} }
throw new UnsupportedOperationException( "UserType does not support reading CallableStatement parameter values: " + userType ); throw new UnsupportedOperationException( "UserType does not support reading CallableStatement parameter values: " + userType );
@ -118,22 +126,58 @@ public class UserTypeSqlTypeAdapter<J> implements JdbcType {
public J extract(CallableStatement statement, String paramName, WrapperOptions options) throws SQLException { public J extract(CallableStatement statement, String paramName, WrapperOptions options) throws SQLException {
if ( userType instanceof ProcedureParameterExtractionAware ) { if ( userType instanceof ProcedureParameterExtractionAware ) {
//noinspection unchecked //noinspection unchecked
return ( (ProcedureParameterExtractionAware<J>) userType ).extract( statement, paramName, options.getSession() ); final J extracted = ( (ProcedureParameterExtractionAware<J>) userType ).extract( statement, paramName, options.getSession() );
logExtracted( paramName, extracted );
return extracted;
} }
throw new UnsupportedOperationException( "UserType does not support reading CallableStatement parameter values: " + userType ); throw new UnsupportedOperationException( "UserType does not support reading CallableStatement parameter values: " + userType );
} }
private void logExtracted(int paramIndex, J extracted) {
if ( ! JdbcExtractingLogging.TRACE_ENABLED ) {
return;
}
if ( extracted == null ) {
JdbcExtractingLogging.logNullExtracted( paramIndex, userType.sqlTypes()[0] );
}
else {
JdbcExtractingLogging.logExtracted( paramIndex, userType.sqlTypes()[0], extracted );
}
}
private void logExtracted(String paramName, J extracted) {
if ( ! JdbcExtractingLogging.TRACE_ENABLED ) {
return;
}
if ( extracted == null ) {
JdbcExtractingLogging.logNullExtracted( paramName, userType.sqlTypes()[0] );
}
else {
JdbcExtractingLogging.logExtracted( paramName, userType.sqlTypes()[0], extracted );
}
}
} }
private static class ValueBinderImpl<J> implements ValueBinder<J> { private static class ValueBinderImpl<J> implements ValueBinder<J> {
private final UserType<J> userType; private final UserType<J> userType;
public ValueBinderImpl(UserType<J> userType) { public ValueBinderImpl(UserType<J> userType, TypeConfiguration typeConfiguration) {
this.userType = userType; this.userType = userType;
} }
@Override @Override
public void bind(PreparedStatement st, J value, int index, WrapperOptions options) throws SQLException { public void bind(PreparedStatement st, J value, int index, WrapperOptions options) throws SQLException {
if ( JdbcBindingLogging.TRACE_ENABLED ) {
if ( value == null ) {
JdbcBindingLogging.logNullBinding( index, userType.sqlTypes()[ 0 ] );
}
else {
JdbcBindingLogging.logBinding( index, userType.sqlTypes()[ 0 ], value );
}
}
userType.nullSafeSet( st, value, index, options.getSession() ); userType.nullSafeSet( st, value, index, options.getSession() );
} }

View File

@ -11,7 +11,6 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
/** /**
@ -52,9 +51,10 @@ public interface UserType<J> {
/** /**
* Return the SQL type codes for the columns mapped by this type. The * Return the SQL type codes for the columns mapped by this type. The
* codes are defined on {@code java.sql.Types}. * codes are generally defined on {@code java.sql.Types}, but could
* be database-specific codes
*
* @see java.sql.Types * @see java.sql.Types
* @return int[] the typecodes
*/ */
int[] sqlTypes(); int[] sqlTypes();
@ -68,17 +68,13 @@ public interface UserType<J> {
/** /**
* Compare two instances of the class mapped by this type for persistence "equality". * Compare two instances of the class mapped by this type for persistence "equality".
* Equality of the persistent state. * Equality of the persistent state.
*
* @param x
* @param y
* @return boolean
*/ */
boolean equals(Object x, Object y) throws HibernateException; boolean equals(Object x, Object y);
/** /**
* Get a hashcode for the instance, consistent with persistence "equality" * Get a hashcode for the instance, consistent with persistence "equality"
*/ */
int hashCode(Object x) throws HibernateException; int hashCode(Object x);
/** /**
* Retrieve an instance of the mapped class from a JDBC resultset. Implementors * Retrieve an instance of the mapped class from a JDBC resultset. Implementors
@ -101,7 +97,7 @@ public interface UserType<J> {
* @param value the object to be cloned, which may be null * @param value the object to be cloned, which may be null
* @return Object a copy * @return Object a copy
*/ */
Object deepCopy(Object value) throws HibernateException; Object deepCopy(Object value);
/** /**
* Are objects of this type mutable? * Are objects of this type mutable?
@ -118,9 +114,8 @@ public interface UserType<J> {
* *
* @param value the object to be cached * @param value the object to be cached
* @return a cacheable representation of the object * @return a cacheable representation of the object
* @throws HibernateException
*/ */
Serializable disassemble(Object value) throws HibernateException; Serializable disassemble(Object value);
/** /**
* Reconstruct an object from the cacheable representation. At the very least this * Reconstruct an object from the cacheable representation. At the very least this
@ -129,9 +124,8 @@ public interface UserType<J> {
* @param cached the object to be cached * @param cached the object to be cached
* @param owner the owner of the cached object * @param owner the owner of the cached object
* @return a reconstructed object from the cacheable representation * @return a reconstructed object from the cacheable representation
* @throws HibernateException
*/ */
Object assemble(Serializable cached, Object owner) throws HibernateException; Object assemble(Serializable cached, Object owner);
/** /**
* During merge, replace the existing (target) value in the entity we are merging to * During merge, replace the existing (target) value in the entity we are merging to
@ -140,9 +134,10 @@ public interface UserType<J> {
* mutable objects, it is safe to return a copy of the first parameter. For objects * mutable objects, it is safe to return a copy of the first parameter. For objects
* with component values, it might make sense to recursively replace component values. * with component values, it might make sense to recursively replace component values.
* *
* @param original the value from the detached entity being merged * @param detached the value from the detached entity being merged
* @param target the value in the managed entity * @param managed the value in the managed entity
*
* @return the value to be merged * @return the value to be merged
*/ */
Object replace(Object original, Object target, Object owner) throws HibernateException; Object replace(Object detached, Object managed, Object owner);
} }

View File

@ -21,7 +21,7 @@ import org.hibernate.usertype.UserType;
/** /**
* @author Emmanuel Bernard * @author Emmanuel Bernard
*/ */
public class StateType implements UserType { public class StateType implements UserType<State> {
public int[] sqlTypes() { public int[] sqlTypes() {
return new int[] { return new int[] {
Types.INTEGER Types.INTEGER
@ -41,19 +41,19 @@ public class StateType implements UserType {
} }
@Override @Override
public Object nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException { public State nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException {
int result = rs.getInt( position ); int result = rs.getInt( position );
if ( rs.wasNull() ) return null; if ( rs.wasNull() ) return null;
return State.values()[result]; return State.values()[result];
} }
@Override @Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException { public void nullSafeSet(PreparedStatement st, State value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException {
if (value == null) { if (value == null) {
st.setNull( index, Types.INTEGER ); st.setNull( index, Types.INTEGER );
} }
else { else {
st.setInt( index, ( (State) value ).ordinal() ); st.setInt( index, value.ordinal() );
} }
} }

View File

@ -14,7 +14,7 @@ import jakarta.persistence.OneToMany;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.hibernate.boot.MetadataSources; import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.SessionFactoryBuilder; import org.hibernate.boot.SessionFactoryBuilder;
import org.hibernate.collection.internal.PersistentSet; import org.hibernate.collection.spi.PersistentSet;
import org.hibernate.engine.spi.PersistentAttributeInterceptable; import org.hibernate.engine.spi.PersistentAttributeInterceptable;
import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.HibernateProxy;
import org.hibernate.stat.Statistics; import org.hibernate.stat.Statistics;

View File

@ -16,7 +16,7 @@ import jakarta.persistence.OneToMany;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.hibernate.boot.MetadataSources; import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.SessionFactoryBuilder; import org.hibernate.boot.SessionFactoryBuilder;
import org.hibernate.collection.internal.PersistentSet; import org.hibernate.collection.spi.PersistentSet;
import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.HibernateProxy;
import org.hibernate.stat.Statistics; import org.hibernate.stat.Statistics;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;

View File

@ -8,7 +8,7 @@ package org.hibernate.orm.test.collection.bag;
import java.util.ArrayList; import java.util.ArrayList;
import org.hibernate.collection.internal.PersistentBag; import org.hibernate.collection.spi.PersistentBag;
import org.hibernate.testing.orm.junit.DialectFeatureChecks; import org.hibernate.testing.orm.junit.DialectFeatureChecks;
import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModel;

View File

@ -18,7 +18,7 @@ import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany; import jakarta.persistence.OneToMany;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.hibernate.collection.internal.AbstractPersistentCollection; import org.hibernate.collection.spi.AbstractPersistentCollection;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModel;

View File

@ -19,7 +19,7 @@ import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany; import jakarta.persistence.OneToMany;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.hibernate.collection.internal.AbstractPersistentCollection; import org.hibernate.collection.spi.AbstractPersistentCollection;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModel;

View File

@ -23,11 +23,10 @@ import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany; import jakarta.persistence.OneToMany;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.hibernate.collection.internal.AbstractPersistentCollection; import org.hibernate.collection.spi.AbstractPersistentCollection;
import org.hibernate.type.CollectionType; import org.hibernate.type.CollectionType;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.logger.Triggerable;
import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.LoggingInspections; import org.hibernate.testing.orm.junit.LoggingInspections;
import org.hibernate.testing.orm.junit.LoggingInspectionsScope; import org.hibernate.testing.orm.junit.LoggingInspectionsScope;

View File

@ -25,7 +25,7 @@ package org.hibernate.orm.test.collection.dereferenced;
import java.util.HashSet; import java.util.HashSet;
import org.hibernate.collection.internal.AbstractPersistentCollection; import org.hibernate.collection.spi.AbstractPersistentCollection;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.CollectionEntry; import org.hibernate.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityEntry;

View File

@ -25,7 +25,7 @@ package org.hibernate.orm.test.collection.dereferenced;
import java.util.HashSet; import java.util.HashSet;
import org.hibernate.collection.internal.AbstractPersistentCollection; import org.hibernate.collection.spi.AbstractPersistentCollection;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.CollectionEntry; import org.hibernate.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityEntry;

View File

@ -25,7 +25,7 @@ package org.hibernate.orm.test.collection.dereferenced;
import java.util.HashSet; import java.util.HashSet;
import org.hibernate.collection.internal.AbstractPersistentCollection; import org.hibernate.collection.spi.AbstractPersistentCollection;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.CollectionEntry; import org.hibernate.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityEntry;

View File

@ -25,7 +25,7 @@ package org.hibernate.orm.test.collection.dereferenced;
import java.util.HashSet; import java.util.HashSet;
import org.hibernate.collection.internal.AbstractPersistentCollection; import org.hibernate.collection.spi.AbstractPersistentCollection;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.CollectionEntry; import org.hibernate.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityEntry;

View File

@ -8,7 +8,7 @@ package org.hibernate.orm.test.collection.idbag;
import java.util.ArrayList; import java.util.ArrayList;
import org.hibernate.collection.internal.PersistentIdentifierBag; import org.hibernate.collection.spi.PersistentIdentifierBag;
import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactory;

View File

@ -12,7 +12,7 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.hibernate.collection.internal.PersistentList; import org.hibernate.collection.spi.PersistentList;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;

View File

@ -22,7 +22,7 @@ import jakarta.persistence.MapKeyColumn;
import jakarta.persistence.OneToMany; import jakarta.persistence.OneToMany;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import org.hibernate.collection.internal.PersistentMap; import org.hibernate.collection.spi.PersistentMap;
import org.hibernate.query.Query; import org.hibernate.query.Query;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;

View File

@ -35,7 +35,7 @@ import jakarta.persistence.OneToMany;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.collection.internal.AbstractPersistentCollection; import org.hibernate.collection.spi.AbstractPersistentCollection;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.CollectionEntry; import org.hibernate.engine.spi.CollectionEntry;

View File

@ -33,8 +33,8 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany; import jakarta.persistence.OneToMany;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import org.hibernate.collection.internal.AbstractPersistentCollection; import org.hibernate.collection.spi.AbstractPersistentCollection;
import org.hibernate.collection.internal.PersistentSet; import org.hibernate.collection.spi.PersistentSet;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.CollectionEntry; import org.hibernate.engine.spi.CollectionEntry;
import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreLogging;

View File

@ -13,7 +13,7 @@ import jakarta.persistence.criteria.Root;
import org.hibernate.CacheMode; import org.hibernate.CacheMode;
import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.AvailableSettings;
import org.hibernate.collection.internal.PersistentSet; import org.hibernate.collection.spi.PersistentSet;
import org.hibernate.query.Query; import org.hibernate.query.Query;
import org.hibernate.stat.CollectionStatistics; import org.hibernate.stat.CollectionStatistics;

View File

@ -16,7 +16,7 @@ import jakarta.persistence.criteria.CriteriaQuery;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.Transaction; import org.hibernate.Transaction;
import org.hibernate.collection.internal.PersistentSet; import org.hibernate.collection.spi.PersistentSet;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.dialect.AbstractHANADialect; import org.hibernate.dialect.AbstractHANADialect;
import org.hibernate.event.spi.AbstractCollectionEvent; import org.hibernate.event.spi.AbstractCollectionEvent;

View File

@ -126,7 +126,7 @@ public class QueryParametersValidationTest extends BaseEntityManagerFunctionalTe
private boolean active; private boolean active;
} }
public static class BooleanUserType implements UserType { public static class BooleanUserType implements UserType<Boolean> {
@Override @Override
public int[] sqlTypes() { public int[] sqlTypes() {
@ -149,15 +149,17 @@ public class QueryParametersValidationTest extends BaseEntityManagerFunctionalTe
} }
@Override @Override
public Object nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException { public Boolean nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException {
return "Y".equals( rs.getString( position ) ); return "Y".equals( rs.getString( position ) );
} }
@Override @Override
public void nullSafeSet( public void nullSafeSet(
PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) PreparedStatement st,
throws HibernateException, SQLException { Boolean value,
st.setString(index, ((Boolean) value).booleanValue() ? "Y" : "N"); int index,
SharedSessionContractImplementor session) throws SQLException {
st.setString(index, value ? "Y" : "N");
} }
@Override @Override

View File

@ -0,0 +1,38 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.mapping.collections.asbasic;
import java.util.Arrays;
import java.util.List;
import jakarta.persistence.AttributeConverter;
import static org.hibernate.internal.util.StringHelper.join;
/**
* @author Steve Ebersole
*/
//tag::ex-csv-converter[]
public class CommaDelimitedStringsConverter implements AttributeConverter<List<String>,String> {
@Override
public String convertToDatabaseColumn(List<String> attributeValue) {
if ( attributeValue == null ) {
return null;
}
return join( ",", attributeValue );
}
@Override
public List<String> convertToEntityAttribute(String dbData) {
if ( dbData == null ) {
return null;
}
return Arrays.asList( dbData.split( "," ) );
}
}
//end::ex-csv-converter[]

View File

@ -0,0 +1,116 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.mapping.collections.asbasic;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.mapping.BasicValue;
import org.hibernate.mapping.Property;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.DomainModelScope;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import jakarta.persistence.Basic;
import jakarta.persistence.Convert;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Steve Ebersole
*/
@DomainModel( annotatedClasses = CommaDelimitedStringsConverterTests.Person.class )
@SessionFactory
public class CommaDelimitedStringsConverterTests {
@Test
public void verifyModel(DomainModelScope scope) {
scope.withHierarchy( Person.class, (entityDescriptor) -> {
final Property nickNamesProperty = entityDescriptor.getProperty( "nickNames" );
assertThat( nickNamesProperty.getValue() ).isInstanceOf( BasicValue.class );
final BasicValue valueMapping = (BasicValue) nickNamesProperty.getValue();
final BasicValue.Resolution<?> resolution = valueMapping.resolve();
assertThat( resolution.getValueConverter() ).isNotNull();
assertThat( resolution.getDomainJavaDescriptor().getJavaTypeClass() ).isEqualTo( List.class );
assertThat( resolution.getRelationalJavaDescriptor().getJavaTypeClass() ).isEqualTo( String.class );
} );
}
@Test
public void basicUsageTest(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
final Person person = new Person( 1, "John Doe" );
person.nickNames.add( "John Q. Public" );
person.nickNames.add( "Joe Public" );
session.persist( person );
} );
scope.inTransaction( (session) -> {
final Person loaded = session.byId( Person.class ).load( 1 );
assertThat( loaded.nickNames ).hasSize( 2 );
assertThat( loaded.nickNames ).containsExactly( "John Q. Public", "Joe Public" );
} );
}
@AfterEach
public void dropTestData(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
session.createQuery( "delete Person" ).executeUpdate();
} );
}
@Table( name = "Person" )
//tag::ex-csv-converter-model[]
@Entity( name = "Person" )
public static class Person {
@Id
private Integer id;
@Basic
private String name;
@Basic
@Convert( converter = CommaDelimitedStringsConverter.class )
private List<String> nickNames;
// ...
//end::ex-csv-converter-model[]
private Person() {
// for use by Hibernate
}
public Person(Integer id, String name) {
this.id = id;
this.name = name;
this.nickNames = new ArrayList<>();
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//tag::ex-csv-converter-model[]
}
//end::ex-csv-converter-model[]
}

View File

@ -0,0 +1,56 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.mapping.collections.classification;
import jakarta.persistence.Access;
import jakarta.persistence.AccessType;
import jakarta.persistence.Embeddable;
/**
* @author Steve Ebersole
*/
//tag::collections-name-ex[]
@Embeddable
@Access( AccessType.FIELD )
public class Name implements Comparable<Name> {
private String first;
private String last;
// ...
//end::collections-name-ex[]
private Name() {
// used by Hibernate
}
public Name(String first, String last) {
this.first = first;
this.last = last;
}
public String getFirst() {
return first;
}
public void setFirst(String first) {
this.first = first;
}
public String getLast() {
return last;
}
public void setLast(String last) {
this.last = last;
}
@Override
public int compareTo(Name o) {
return NameComparator.comparator.compare( this, o );
}
//tag::collections-name-ex[]
}
//end::collections-name-ex[]

View File

@ -0,0 +1,24 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.mapping.collections.classification;
import java.util.Comparator;
/**
* @author Steve Ebersole
*/
//tag::collections-name-comparator-ex[]
public class NameComparator implements Comparator<Name> {
static final Comparator<Name> comparator = Comparator.comparing( Name::getLast ).thenComparing( Name::getFirst );
@Override
public int compare(Name o1, Name o2) {
return comparator.compare( o1, o2 );
}
}
//end::collections-name-comparator-ex[]

View File

@ -0,0 +1,35 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.mapping.collections.classification.bag;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Property;
import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.DomainModelScope;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Steve Ebersole
*/
@DomainModel( annotatedClasses = {
EntityWithBagAsCollection.class
} )
public class BagTests {
@Test
public void verifyCollectionAsBag(DomainModelScope scope) {
scope.withHierarchy( EntityWithBagAsCollection.class, (entityDescriptor) -> {
final Property names = entityDescriptor.getProperty( "names" );
final Collection namesMapping = (Collection) names.getValue();
assertThat( namesMapping.getCollectionSemantics().getCollectionClassification() ).isEqualTo( CollectionClassification.BAG );
} );
}
}

View File

@ -0,0 +1,59 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.mapping.collections.classification.bag;
import java.util.Collection;
import org.hibernate.orm.test.mapping.collections.classification.Name;
import jakarta.persistence.Basic;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
/**
* @author Steve Ebersole
*/
//tag::collections-bag-ex[]
@Entity
public class EntityWithBagAsCollection {
// ..
//end::collections-bag-ex[]
@Id
private Integer id;
@Basic
private String name;
//tag::collections-bag-ex[]
@ElementCollection
private Collection<Name> names;
//end::collections-bag-ex[]
private EntityWithBagAsCollection() {
// for Hibernate use
}
public EntityWithBagAsCollection(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//tag::collections-bag-ex[]
}
//end::collections-bag-ex[]

View File

@ -0,0 +1,65 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.mapping.collections.classification.bag;
import java.util.Collection;
import java.util.List;
import org.hibernate.annotations.CollectionClassificationType;
import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.orm.test.mapping.collections.classification.Name;
import jakarta.persistence.Basic;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import static org.hibernate.metamodel.CollectionClassification.BAG;
/**
* @author Steve Ebersole
*/
//tag::collections-bag-list-ex[]
@Entity
public class EntityWithBagAsList {
// ..
//end::collections-bag-list-ex[]
@Id
private Integer id;
@Basic
private String name;
//tag::collections-bag-list-ex[]
@ElementCollection
@CollectionClassificationType( BAG )
private List<Name> names;
//end::collections-bag-list-ex[]
private EntityWithBagAsList() {
// for Hibernate use
}
public EntityWithBagAsList(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//tag::collections-bag-list-ex[]
}
//end::collections-bag-list-ex[]

View File

@ -0,0 +1,63 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.mapping.collections.classification.explicit;
import java.util.Collection;
import org.hibernate.annotations.CollectionClassificationType;
import org.hibernate.orm.test.mapping.collections.classification.Name;
import jakarta.persistence.Basic;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import static org.hibernate.metamodel.CollectionClassification.SET;
/**
* @author Steve Ebersole
*/
//tag::collections-bag-set-ex[]
@Entity
public class EntityWithExplicitSetClassification {
// ...
//end::collections-bag-set-ex[]
@Id
private Integer id;
@Basic
private String name;
//tag::collections-bag-set-ex[]
@ElementCollection
@CollectionClassificationType(SET)
private Collection<Name> names;
//end::collections-bag-set-ex[]
private EntityWithExplicitSetClassification() {
// for Hibernate use
}
public EntityWithExplicitSetClassification(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//tag::collections-bag-set-ex[]
}
//end::collections-bag-set-ex[]

View File

@ -0,0 +1,66 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.mapping.collections.classification.list;/**
* @author Steve Ebersole
*/
import java.util.List;
import org.hibernate.annotations.ListIndexBase;
import org.hibernate.orm.test.mapping.collections.classification.Name;
import jakarta.persistence.Basic;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.OrderColumn;
/**
* @author Steve Ebersole
*/ //tag::collections-list-indexbase-ex[]
@Entity
public class EntityWithIndexBasedList {
// ...
//end::collections-list-indexbase-ex[]
@Id
private Integer id;
@Basic
private String name;
//tag::collections-list-indexbase-ex[]
@ElementCollection
@OrderColumn(name = "name_index")
@ListIndexBase(1)
private List<Name> names;
//end::collections-list-indexbase-ex[]
private EntityWithIndexBasedList() {
// for Hibernate use
}
public EntityWithIndexBasedList(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//tag::collections-list-indexbase-ex[]
}
//end::collections-list-indexbase-ex[]

View File

@ -0,0 +1,62 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.mapping.collections.classification.list;/**
* @author Steve Ebersole
*/
import java.util.List;
import org.hibernate.orm.test.mapping.collections.classification.Name;
import jakarta.persistence.Basic;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
/**
* @author Steve Ebersole
*/ //tag::collections-list-ex[]
@Entity
public class EntityWithList {
// ...
//end::collections-list-ex[]
@Id
private Integer id;
@Basic
private String name;
//tag::collections-list-ex[]
@ElementCollection
private List<Name> names;
//end::collections-list-ex[]
private EntityWithList() {
// for Hibernate use
}
public EntityWithList(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//tag::collections-list-ex[]
}
//end::collections-list-ex[]

View File

@ -0,0 +1,62 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.mapping.collections.classification.list;
import java.util.List;
import org.hibernate.orm.test.mapping.collections.classification.Name;
import jakarta.persistence.Basic;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.OrderColumn;
/**
* @author Steve Ebersole
*/
//tag::collections-list-ordercolumn-ex[]
@Entity
public class EntityWithOrderColumnList {
// ...
//end::collections-list-ordercolumn-ex[]
@Id
private Integer id;
@Basic
private String name;
//tag::collections-list-ordercolumn-ex[]
@ElementCollection
@OrderColumn( name = "name_index" )
private List<Name> names;
//end::collections-list-ordercolumn-ex[]
private EntityWithOrderColumnList() {
// for Hibernate use
}
public EntityWithOrderColumnList(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//tag::collections-list-ordercolumn-ex[]
}
//end::collections-list-ordercolumn-ex[]

Some files were not shown because too many files have changed in this diff Show More