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 types
=== Basic values
:rootProjectDir: ../../../../../../..
:documentationProjectDir: {rootProjectDir}/documentation
:coreProjectDir: {rootProjectDir}/hibernate-core

View File

@ -1,5 +1,5 @@
[[embeddables]]
=== Embeddable types
=== Embeddable values
:rootProjectDir: ../../../../../../..
:sourcedir: ../../../../../test/java/org/hibernate/userguide/mapping/embeddable
: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 )
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.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.OrderColumn;
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
@ -63,11 +64,11 @@ public class BasicTypeElementCollectionTest extends BaseEntityManagerFunctionalT
doInJPA(this::entityManagerFactory, entityManager -> {
Person person = entityManager.find(Person.class, 1L);
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().add("123-456-7890");
person.getPhones().add("456-000-1234");
//end::collections-value-type-collection-lifecycle-example[]
//end::ex-collection-elemental-lifecycle[]
});
doInJPA(this::entityManagerFactory, entityManager -> {
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")
public static class Person {
@ -86,16 +87,17 @@ public class BasicTypeElementCollectionTest extends BaseEntityManagerFunctionalT
private Long id;
@ElementCollection
@OrderColumn( name = "_position")
private List<String> phones = new ArrayList<>();
//Getters and setters are omitted for brevity
//end::collections-collection-proxy-entity-example[]
//end::ex-collection-elemental-basic-model[]
public List<String> getPhones() {
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.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
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")
public static class Person {
@ -57,12 +59,12 @@ public class EmbeddableTypeElementCollectionTest extends BaseEntityManagerFuncti
//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() {
return phones;
}
//tag::collections-embeddable-type-collection-lifecycle-entity-example[]
//tag::ex-collection-elemental-basic-model[]
}
@Embeddable
@ -75,7 +77,7 @@ public class EmbeddableTypeElementCollectionTest extends BaseEntityManagerFuncti
//Getters and setters are omitted for brevity
//end::collections-embeddable-type-collection-lifecycle-entity-example[]
//end::ex-collection-elemental-basic-model[]
public Phone() {
}
@ -92,7 +94,7 @@ public class EmbeddableTypeElementCollectionTest extends BaseEntityManagerFuncti
public String getNumber() {
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.NaturalId;
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
import org.hibernate.userguide.collections.type.QueueType;
import org.junit.Test;
@ -70,7 +71,7 @@ public class QueueTest extends BaseEntityManagerFunctionalTestCase {
private Long id;
@OneToMany(cascade = CascadeType.ALL)
@CollectionType(type = "org.hibernate.userguide.collections.type.QueueType")
@CollectionType(type = QueueType.class )
private Collection<Phone> phones = new LinkedList<>();
//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.Queue;
import org.hibernate.collection.internal.PersistentBag;
import org.hibernate.collection.spi.PersistentBag;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
//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.EnhancementAsProxyLazinessInterceptor;
import org.hibernate.collection.internal.PersistentBag;
import org.hibernate.collection.internal.PersistentList;
import org.hibernate.collection.internal.PersistentMap;
import org.hibernate.collection.internal.PersistentSet;
import org.hibernate.collection.internal.PersistentSortedMap;
import org.hibernate.collection.internal.PersistentSortedSet;
import org.hibernate.collection.spi.PersistentBag;
import org.hibernate.collection.spi.PersistentList;
import org.hibernate.collection.spi.PersistentMap;
import org.hibernate.collection.spi.PersistentSet;
import org.hibernate.collection.spi.PersistentSortedMap;
import org.hibernate.collection.spi.PersistentSortedSet;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.HibernateIterator;
import org.hibernate.engine.jdbc.LobCreator;

View File

@ -7,7 +7,7 @@
package org.hibernate.action.internal;
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.engine.spi.CollectionEntry;
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 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.METHOD;
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
* the Hibernate Type of the collection elements.
*
* @see org.hibernate.type.CollectionType
* @see org.hibernate.usertype.UserCollectionType
* Names a custom collection type for a persistent collection.
*
* @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)
@Deprecated
public @interface CollectionType {
/**
* Names the type.
*
* Could name the implementation class (an implementation of {@link org.hibernate.type.CollectionType} or
* {@link org.hibernate.usertype.UserCollectionType}).
* Specifies the UserCollectionType to use when mapping the attribute
* to which this annotation is attached.
*/
String type();
Class<? extends UserCollectionType> type();
/**
* Specifies the class to use the semantics of.

View File

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

View File

@ -6,7 +6,6 @@
*/
package org.hibernate.cfg;
import java.util.List;
import java.util.function.Supplier;
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.spi.SessionFactoryOptions;
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.jpa.spi.JpaCompliance;
import org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode;
@ -2116,8 +2117,8 @@ public interface AvailableSettings {
/**
* Controls whether Hibernate should recognize what it considers a "bag"
* ({@link org.hibernate.collection.internal.PersistentBag}) as a List
* ({@link org.hibernate.collection.internal.PersistentList}) or as a bag.
* ({@link PersistentBag}) as a List
* ({@link PersistentList}) or as a bag.
*
* If enabled, we will recognize it as a List where {@link jakarta.persistence.OrderColumn}
* 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"
* ({@link org.hibernate.collection.internal.PersistentBag}) as a List
* ({@link org.hibernate.collection.internal.PersistentList}) or as a bag.
* ({@link PersistentBag}) as a List
* ({@link PersistentList}) or as a bag.
*
* If enabled, we will recognize it as a List where {@link jakarta.persistence.OrderColumn}
* 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.CollectionIdJdbcType;
import org.hibernate.annotations.CollectionIdJdbcTypeCode;
import org.hibernate.annotations.CollectionSemantics;
import org.hibernate.annotations.CollectionType;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.Filter;
@ -103,6 +104,8 @@ import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table;
import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.metamodel.EmbeddableInstantiator;
import org.hibernate.resource.beans.spi.ManagedBean;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
import org.jboss.logging.Logger;
@ -278,28 +281,48 @@ public abstract class CollectionBinder {
XProperty property,
boolean isHibernateExtensionMapping,
MetadataBuildingContext buildingContext) {
final CollectionType typeAnnotation = property.getAnnotation( CollectionType.class );
final CollectionType typeAnnotation = HCANNHelper.findAnnotation( property, CollectionType.class );
final CollectionBinder binder;
if ( typeAnnotation != null ) {
binder = createBinderFromCustomTypeAnnotation( property, typeAnnotation, buildingContext );
}
else {
binder = createBinderFromProperty( property, buildingContext );
}
binder.setIsHibernateExtensionMapping( isHibernateExtensionMapping );
if ( typeAnnotation != null ) {
binder.explicitType = typeAnnotation.type();
binder.explicitType = typeAnnotation.type().getName();
for ( Parameter param : typeAnnotation.parameters() ) {
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;
}
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(
XProperty property,
MetadataBuildingContext buildingContext) {

View File

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

View File

@ -8,6 +8,8 @@ package org.hibernate.collection.internal;
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.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.CollectionClassification;

View File

@ -8,7 +8,9 @@ package org.hibernate.collection.internal;
import java.util.Collection;
import org.hibernate.collection.spi.AbstractBagSemantics;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.collection.spi.PersistentIdentifierBag;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.CollectionClassification;
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.InitializerProducerBuilder;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.collection.spi.PersistentList;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.CollectionClassification;

View File

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

View File

@ -8,9 +8,10 @@ package org.hibernate.collection.internal;
import java.util.Iterator;
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.PersistentMap;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.CollectionClassification;

View File

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

View File

@ -9,6 +9,8 @@ package org.hibernate.collection.internal;
import java.util.HashSet;
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.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.CollectionClassification;

View File

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

View File

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

View File

@ -4,7 +4,7 @@
* 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.collection.internal;
package org.hibernate.collection.spi;
import java.util.ArrayList;
import java.util.Collection;

View File

@ -4,7 +4,7 @@
* 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.collection.internal;
package org.hibernate.collection.spi;
import java.util.Collections;
import java.util.Iterator;

View File

@ -1,10 +1,10 @@
/*
* 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>.
* 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.collection.internal;
package org.hibernate.collection.spi;
import java.io.Serializable;
import java.util.ArrayList;
@ -21,7 +21,6 @@ import org.hibernate.AssertionFailure;
import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.LazyInitializationException;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.internal.ForeignKeys;
import org.hibernate.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.EntityEntry;

View File

@ -4,7 +4,7 @@
* 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.collection.internal;
package org.hibernate.collection.spi;
import java.util.Iterator;
import java.util.Set;

View File

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

View File

@ -23,5 +23,5 @@ import org.hibernate.mapping.Collection;
@Incubating
public interface CollectionSemanticsResolver {
// 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;
import org.hibernate.Incubating;
import org.hibernate.engine.FetchTiming;
import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.metamodel.mapping.CollectionPart;
@ -23,6 +24,7 @@ import org.hibernate.sql.results.graph.collection.internal.SetInitializerProduce
/**
* @author Steve Ebersole
*/
@Incubating
public class InitializerProducerBuilder {
public static CollectionInitializerProducer createInitializerProducer(
NavigablePath navigablePath,

View File

@ -1,10 +1,10 @@
/*
* 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>.
* 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.collection.internal;
package org.hibernate.collection.spi;
import java.io.Serializable;
import java.lang.reflect.Array;
@ -15,27 +15,29 @@ import java.util.Iterator;
import java.util.List;
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.SharedSessionContractImplementor;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.type.Type;
import org.jboss.logging.Logger;
/**
* A persistent wrapper for an array. Lazy initialization
* is NOT supported. Use of Hibernate arrays is not really
* recommended.
*
* @apiNote Incubating in terms of making this non-internal. These contracts
* will be getting cleaned up in following releases.
*
* @author Gavin King
*/
@Incubating
public class PersistentArrayHolder<E> extends AbstractPersistentCollection<E> {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
PersistentArrayHolder.class.getName()
);
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( PersistentArrayHolder.class );
protected Object array;

View File

@ -1,10 +1,10 @@
/*
* 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>.
* 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.collection.internal;
package org.hibernate.collection.spi;
import java.io.Serializable;
import java.util.ArrayList;
@ -17,7 +17,7 @@ import java.util.ListIterator;
import java.util.Map;
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.SharedSessionContractImplementor;
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,
* 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
*/
@Incubating
public class PersistentBag<E> extends AbstractPersistentCollection<E> implements List<E> {
protected List<E> bag;

View File

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

View File

@ -1,10 +1,10 @@
/*
* 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>.
* 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.collection.internal;
package org.hibernate.collection.spi;
import java.io.Serializable;
import java.util.ArrayList;
@ -16,6 +16,7 @@ import java.util.ListIterator;
import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.Incubating;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
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.
* 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
*/
@Incubating
public class PersistentIdentifierBag<E> extends AbstractPersistentCollection<E> implements List<E> {
protected List<E> values;
protected Map<Integer, Object> identifiers;

View File

@ -1,10 +1,10 @@
/*
* 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>.
* 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.collection.internal;
package org.hibernate.collection.spi;
import java.io.Serializable;
import java.util.ArrayList;
@ -14,6 +14,7 @@ import java.util.List;
import java.util.ListIterator;
import org.hibernate.HibernateException;
import org.hibernate.Incubating;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
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
* 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
*/
@Incubating
public class PersistentList<E> extends AbstractPersistentCollection<E> implements List<E> {
protected List<E> list;
@ -81,6 +85,10 @@ public class PersistentList<E> extends AbstractPersistentCollection<E> implement
this( (SharedSessionContractImplementor) session, list );
}
protected List<E> getRawList() {
return list;
}
@Override
public Serializable getSnapshot(CollectionPersister persister) throws HibernateException {
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) {
super( addedValue, null );

View File

@ -1,10 +1,10 @@
/*
* 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>.
* 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.collection.internal;
package org.hibernate.collection.spi;
import java.io.Serializable;
import java.util.ArrayList;
@ -16,6 +16,7 @@ import java.util.Map;
import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.Incubating;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
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
* 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
*/
@Incubating
public class PersistentMap<K,E> extends AbstractPersistentCollection<E> implements Map<K,E> {
protected Map<K,E> map;

View File

@ -1,10 +1,10 @@
/*
* 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>.
* 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.collection.internal;
package org.hibernate.collection.spi;
import java.io.Serializable;
import java.util.ArrayList;
@ -15,6 +15,8 @@ import java.util.List;
import java.util.Set;
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.SharedSessionContractImplementor;
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
* 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
*/
@Incubating
public class PersistentSet<E> extends AbstractPersistentCollection<E> implements Set<E> {
protected Set<E> set;

View File

@ -1,10 +1,10 @@
/*
* 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>.
* 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.collection.internal;
package org.hibernate.collection.spi;
import java.io.Serializable;
import java.util.Collection;
@ -15,6 +15,7 @@ import java.util.SortedMap;
import java.util.TreeMap;
import org.hibernate.HibernateException;
import org.hibernate.Incubating;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
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
* 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>
*/
@Incubating
public class PersistentSortedMap<K,E> extends PersistentMap<K,E> implements SortedMap<K,E> {
protected Comparator<? super K> comparator;

View File

@ -1,10 +1,10 @@
/*
* 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>.
* 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.collection.internal;
package org.hibernate.collection.spi;
import java.io.Serializable;
import java.util.Comparator;
@ -12,6 +12,7 @@ import java.util.SortedSet;
import java.util.TreeMap;
import org.hibernate.HibernateException;
import org.hibernate.Incubating;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
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
* 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>
*/
@Incubating
public class PersistentSortedSet<E> extends PersistentSet<E> implements SortedSet<E> {
protected Comparator<? super E> comparator;

View File

@ -15,7 +15,7 @@ import java.util.Collection;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
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.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;

View File

@ -43,8 +43,8 @@ public interface JpaCompliance {
* JPA does not have.
*
* If enabled, Hibernate will recognize this condition as defining
* a {@link org.hibernate.collection.internal.PersistentList}, otherwise
* Hibernate will treat is as a {@link org.hibernate.collection.internal.PersistentBag}
* a {@link org.hibernate.collection.spi.PersistentList}, otherwise
* 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
* 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 org.hibernate.collection.internal.PersistentArrayHolder;
import org.hibernate.collection.spi.PersistentArrayHolder;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
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 org.hibernate.LockMode;
import org.hibernate.collection.internal.PersistentArrayHolder;
import org.hibernate.collection.spi.PersistentArrayHolder;
import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.internal.log.LoggingHelper;
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 org.hibernate.LockMode;
import org.hibernate.collection.internal.PersistentBag;
import org.hibernate.collection.internal.PersistentIdentifierBag;
import org.hibernate.collection.spi.PersistentBag;
import org.hibernate.collection.spi.PersistentIdentifierBag;
import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.internal.log.LoggingHelper;
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 org.hibernate.LockMode;
import org.hibernate.collection.internal.PersistentList;
import org.hibernate.collection.spi.PersistentList;
import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.internal.log.LoggingHelper;
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 org.hibernate.LockMode;
import org.hibernate.collection.internal.PersistentMap;
import org.hibernate.collection.spi.PersistentMap;
import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.internal.log.LoggingHelper;
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 org.hibernate.LockMode;
import org.hibernate.collection.internal.PersistentSet;
import org.hibernate.collection.spi.PersistentSet;
import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.internal.log.LoggingHelper;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;

View File

@ -14,11 +14,10 @@ import java.util.function.Supplier;
import org.hibernate.CacheMode;
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.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.engine.spi.BatchFetchQueue;
import org.hibernate.engine.spi.CollectionEntry;

View File

@ -16,7 +16,7 @@ import java.util.Map;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
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.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;

View File

@ -10,7 +10,7 @@ import java.util.ArrayList;
import java.util.Collection;
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.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister;

View File

@ -23,7 +23,7 @@ import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.NotYetImplementedFor6Exception;
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.engine.jdbc.Size;
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
this.jdbcType = new UserTypeSqlTypeAdapter<>( userType, mappedJavaTypeDescriptor );
this.jdbcType = new UserTypeSqlTypeAdapter<>( userType, mappedJavaTypeDescriptor , typeConfiguration);
this.valueExtractor = jdbcType.getExtractor( mappedJavaTypeDescriptor );
this.valueBinder = jdbcType.getBinder( mappedJavaTypeDescriptor );

View File

@ -9,7 +9,7 @@ package org.hibernate.type;
import java.util.ArrayList;
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.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister;

View File

@ -9,7 +9,7 @@ package org.hibernate.type;
import java.util.ArrayList;
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.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister;

View File

@ -11,7 +11,7 @@ import java.util.Iterator;
import java.util.Map;
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.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister;

View File

@ -6,7 +6,7 @@
*/
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.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;

View File

@ -9,7 +9,7 @@ package org.hibernate.type;
import java.util.Comparator;
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.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister;

View File

@ -9,7 +9,7 @@ package org.hibernate.type;
import java.util.Comparator;
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.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister;

View File

@ -16,4 +16,46 @@ public interface JdbcBindingLogging {
boolean TRACE_ENABLED = LOGGER.isTraceEnabled();
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 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 org.hibernate.type.descriptor.JdbcBindingLogging;
import org.hibernate.type.descriptor.JdbcTypeNameMapper;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.WrapperOptions;
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 {
if ( value == null ) {
if ( JdbcBindingLogging.TRACE_ENABLED ) {
JdbcBindingLogging.LOGGER.trace(
String.format(
NULL_BIND_MSG_TEMPLATE,
index,
JdbcTypeNameMapper.getTypeName( getJdbcTypeDescriptor().getDefaultSqlTypeCode() )
)
JdbcBindingLogging.logNullBinding(
index,
jdbcType.getDefaultSqlTypeCode()
);
}
doBindNull( st, index, options );
}
else {
if ( JdbcBindingLogging.TRACE_ENABLED ) {
JdbcBindingLogging.LOGGER.trace(
String.format(
BIND_MSG_TEMPLATE,
index,
JdbcTypeNameMapper.getTypeName( jdbcType.getDefaultSqlTypeCode() ),
getJavaTypeDescriptor().extractLoggableRepresentation( value )
)
JdbcBindingLogging.logBinding(
index,
jdbcType.getDefaultSqlTypeCode(),
getJavaTypeDescriptor().extractLoggableRepresentation( value )
);
}
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 {
if ( value == null ) {
if ( JdbcBindingLogging.TRACE_ENABLED ) {
JdbcBindingLogging.LOGGER.trace(
String.format(
NULL_BIND_MSG_TEMPLATE,
name,
JdbcTypeNameMapper.getTypeName( getJdbcTypeDescriptor().getDefaultSqlTypeCode() )
)
JdbcBindingLogging.logNullBinding(
name,
jdbcType.getDefaultSqlTypeCode()
);
}
doBindNull( st, name, options );
}
else {
if ( JdbcBindingLogging.TRACE_ENABLED ) {
JdbcBindingLogging.LOGGER.trace(
String.format(
BIND_MSG_TEMPLATE,
name,
JdbcTypeNameMapper.getTypeName( jdbcType.getDefaultSqlTypeCode() ),
getJavaTypeDescriptor().extractLoggableRepresentation( value )
)
JdbcBindingLogging.logBinding(
name,
jdbcType.getDefaultSqlTypeCode(),
getJavaTypeDescriptor().extractLoggableRepresentation( value )
);
}
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 );
if ( value == null || rs.wasNull() ) {
if ( JdbcExtractingLogging.TRACE_ENABLED ) {
JdbcExtractingLogging.LOGGER.tracef(
"extracted value ([%s] : [%s]) - [null]",
JdbcExtractingLogging.logNullExtracted(
paramIndex,
JdbcTypeNameMapper.getTypeName( getJdbcTypeDescriptor().getDefaultSqlTypeCode() )
getJdbcTypeDescriptor().getDefaultSqlTypeCode()
);
}
return null;
}
else {
if ( JdbcExtractingLogging.TRACE_ENABLED ) {
JdbcExtractingLogging.LOGGER.tracef(
"extracted value ([%s] : [%s]) - [%s]",
JdbcExtractingLogging.logExtracted(
paramIndex,
JdbcTypeNameMapper.getTypeName( getJdbcTypeDescriptor().getDefaultSqlTypeCode() ),
getJdbcTypeDescriptor().getDefaultSqlTypeCode(),
getJavaTypeDescriptor().extractLoggableRepresentation( value )
);
}

View File

@ -13,6 +13,8 @@ import java.sql.SQLException;
import org.hibernate.HibernateException;
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.ValueExtractor;
import org.hibernate.type.descriptor.WrapperOptions;
@ -36,12 +38,12 @@ public class UserTypeSqlTypeAdapter<J> implements JdbcType {
private final ValueExtractor<J> valueExtractor;
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.jtd = jtd;
this.valueExtractor = new ValueExtractorImpl<>( userType );
this.valueBinder = new ValueBinderImpl<>( userType );
this.valueExtractor = new ValueExtractorImpl<>( userType, jtd );
this.valueBinder = new ValueBinderImpl<>( userType, typeConfiguration );
}
@Override
@ -94,21 +96,27 @@ public class UserTypeSqlTypeAdapter<J> implements JdbcType {
private static class ValueExtractorImpl<J> implements ValueExtractor<J> {
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.javaType = javaType;
}
@Override
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
public J extract(CallableStatement statement, int paramIndex, WrapperOptions options) throws SQLException {
if ( userType instanceof ProcedureParameterExtractionAware ) {
//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 );
@ -118,22 +126,58 @@ public class UserTypeSqlTypeAdapter<J> implements JdbcType {
public J extract(CallableStatement statement, String paramName, WrapperOptions options) throws SQLException {
if ( userType instanceof ProcedureParameterExtractionAware ) {
//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 );
}
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 final UserType<J> userType;
public ValueBinderImpl(UserType<J> userType) {
public ValueBinderImpl(UserType<J> userType, TypeConfiguration typeConfiguration) {
this.userType = userType;
}
@Override
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() );
}

View File

@ -11,7 +11,6 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.hibernate.HibernateException;
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
* 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
* @return int[] the typecodes
*/
int[] sqlTypes();
@ -68,17 +68,13 @@ public interface UserType<J> {
/**
* Compare two instances of the class mapped by this type for persistence "equality".
* 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"
*/
int hashCode(Object x) throws HibernateException;
int hashCode(Object x);
/**
* 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
* @return Object a copy
*/
Object deepCopy(Object value) throws HibernateException;
Object deepCopy(Object value);
/**
* Are objects of this type mutable?
@ -118,9 +114,8 @@ public interface UserType<J> {
*
* @param value the object to be cached
* @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
@ -129,9 +124,8 @@ public interface UserType<J> {
* @param cached the object to be cached
* @param owner the owner of the cached object
* @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
@ -140,9 +134,10 @@ public interface UserType<J> {
* 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.
*
* @param original the value from the detached entity being merged
* @param target the value in the managed entity
* @param detached the value from the detached entity being merged
* @param managed the value in the managed entity
*
* @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
*/
public class StateType implements UserType {
public class StateType implements UserType<State> {
public int[] sqlTypes() {
return new int[] {
Types.INTEGER
@ -41,19 +41,19 @@ public class StateType implements UserType {
}
@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 );
if ( rs.wasNull() ) return null;
return State.values()[result];
}
@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) {
st.setNull( index, Types.INTEGER );
}
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.boot.MetadataSources;
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.proxy.HibernateProxy;
import org.hibernate.stat.Statistics;

View File

@ -16,7 +16,7 @@ import jakarta.persistence.OneToMany;
import org.hibernate.Hibernate;
import org.hibernate.boot.MetadataSources;
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.stat.Statistics;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;

View File

@ -8,7 +8,7 @@ package org.hibernate.orm.test.collection.bag;
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.DomainModel;

View File

@ -18,7 +18,7 @@ import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
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.orm.junit.DomainModel;

View File

@ -19,7 +19,7 @@ import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
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.orm.junit.DomainModel;

View File

@ -23,11 +23,10 @@ import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import org.hibernate.Hibernate;
import org.hibernate.collection.internal.AbstractPersistentCollection;
import org.hibernate.collection.spi.AbstractPersistentCollection;
import org.hibernate.type.CollectionType;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.logger.Triggerable;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.LoggingInspections;
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 org.hibernate.collection.internal.AbstractPersistentCollection;
import org.hibernate.collection.spi.AbstractPersistentCollection;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.EntityEntry;

View File

@ -25,7 +25,7 @@ package org.hibernate.orm.test.collection.dereferenced;
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.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.EntityEntry;

View File

@ -25,7 +25,7 @@ package org.hibernate.orm.test.collection.dereferenced;
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.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.EntityEntry;

View File

@ -25,7 +25,7 @@ package org.hibernate.orm.test.collection.dereferenced;
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.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.EntityEntry;

View File

@ -8,7 +8,7 @@ package org.hibernate.orm.test.collection.idbag;
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.SessionFactory;

View File

@ -12,7 +12,7 @@ import java.util.ArrayList;
import java.util.HashMap;
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.SessionImplementor;
import org.hibernate.persister.collection.CollectionPersister;

View File

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

View File

@ -35,7 +35,7 @@ import jakarta.persistence.OneToMany;
import org.hibernate.Hibernate;
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.engine.spi.CollectionEntry;

View File

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

View File

@ -13,7 +13,7 @@ import jakarta.persistence.criteria.Root;
import org.hibernate.CacheMode;
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.stat.CollectionStatistics;

View File

@ -16,7 +16,7 @@ import jakarta.persistence.criteria.CriteriaQuery;
import org.hibernate.Session;
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.dialect.AbstractHANADialect;
import org.hibernate.event.spi.AbstractCollectionEvent;

View File

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