HHH-9998 - Continue documentation TLC - mapping basic-types
This commit is contained in:
parent
84987f46b7
commit
4f725332af
|
@ -34,8 +34,8 @@
|
|||
<para>
|
||||
This chapter will describe the characteristics of a persistable domain model. However, it will not discuss
|
||||
defining the mapping for the domain model. That is a massive topic in its own right and is the subject of an
|
||||
entire dedicated manual. See the <citetitle>Hibernate - Domain Model Mapping</citetitle> documentation
|
||||
from the <link xlink:href="http://hibernate.org/documentation">documentation site</link>.
|
||||
entire dedicated manual. See the <citetitle>Hibernate Domain Model Mapping Guide</citetitle> from the
|
||||
<link xlink:href="http://hibernate.org/documentation">documentation site</link>.
|
||||
</para>
|
||||
|
||||
<section xml:id="domainmodel-pojo">
|
||||
|
|
|
@ -48,17 +48,26 @@
|
|||
<xi:include href="chapters/basic/Basic_Types.xml" />
|
||||
<xi:include href="chapters/composition/Composition.xml" />
|
||||
<xi:include href="chapters/collection/Collection.xml" />
|
||||
<xi:include href="chapters/entity/Entity.xml" />
|
||||
<xi:include href="chapters/id/Identifiers.xml" />
|
||||
<xi:include href="chapters/natural_id/Natural_Id.xml" />
|
||||
|
||||
<!--
|
||||
<xi:include href="chapters/entity/Entity.xml" />
|
||||
<xi:include href="chapters/id/Identifiers.xml" />
|
||||
<xi:include href="chapters/association/Associations.xml" />
|
||||
<xi:include href="chapters/natural_id/Natural_Id.xml" />
|
||||
<xi:include href="chapters/secondary/Secondary_Tables.xml" />
|
||||
|
||||
<xi:include href="chapters/constraints/Database_Constraints.xml" /> pk, fk, index, check, unique
|
||||
<xi:include href="chapters/auxiliary/Auxiliary_DB_Objects.xml" />
|
||||
|
||||
<xi:include href="chapters/generation/Generated_attributes.xml" />
|
||||
<xi:include href="chapters/access/Attribute_Access.xml" />
|
||||
<xi:include href="chapters/overrides/Mapping_Overrides.xml" /> AttributeOverrides/AssociationOverrides
|
||||
|
||||
<xi:include href="chapters/generation/Generated_attributes.xml" />
|
||||
|
||||
columns, formulas, read/write-fragments
|
||||
|
||||
<xi:include href="chapters/naming/Naming_Strategies.xml" />
|
||||
<xi:include href="chapters/quoting/SQL_Identifier_Quoting.xml" />
|
||||
-->
|
||||
|
||||
<!-- appendices? -->
|
||||
|
|
|
@ -381,32 +381,43 @@
|
|||
</tgroup>
|
||||
</table>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
To use these hibernate-java8 types just add the hibernate-java8 jar to your classpath; Hibernate
|
||||
will take care of the rest. See <xref linkend="basic-datetime"/>
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<!-- todo : document added hibernate-spatial types -->
|
||||
|
||||
<para>
|
||||
These mappings are managed by a service inside Hibernate called the
|
||||
<classname>org.hibernate.type.BasicTypeRegistry</classname>, which essentially maintains a map of
|
||||
<interface>org.hibernate.type.BasicType</interface> (a <interface>org.hibernate.type.Type</interface>
|
||||
<interfacename>org.hibernate.type.BasicType</interfacename> (a <interfacename>org.hibernate.type.Type</interfacename>
|
||||
specialization) instances keyed by a name. That is the purpose of the "BasicTypeRegistry key(s)" column
|
||||
in the previous tables. We will revisit this detail later.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
||||
<section xml:id="basic-annotation">
|
||||
<title>The <literal>@Basic</literal> annotation</title>
|
||||
|
||||
<para>
|
||||
Strictly speaking, a basic type is denoted with the <interfacename>javax.persistence.Basic</interfacename>
|
||||
annotation. Generally speaking the <literal>@Basic</literal> annotation can be ignored.
|
||||
annotation. Generally speaking the <literal>@Basic</literal> annotation can be ignored. Both of the
|
||||
following examples are ultimately the same.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>With <literal>@Basic</literal></title>
|
||||
<programlisting role="JAVA"><xi:include href="extras/ex1.java" parse="text"/></programlisting>
|
||||
</example>
|
||||
<example>
|
||||
<title>Without <literal>@Basic</literal></title>
|
||||
<programlisting role="JAVA"><xi:include href="extras/ex2.java" parse="text"/></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
Both of the above examples are ultimately the same.
|
||||
</para>
|
||||
|
||||
<tip>
|
||||
<para>
|
||||
The JPA specification strictly limits the Java types that can be marked as
|
||||
|
@ -434,17 +445,71 @@
|
|||
<para>
|
||||
If provider portability is a concern, you should stick to just these basic types. Note that JPA
|
||||
2.1 did add the notion of an <interfacename>javax.persistence.AttributeConverter</interfacename>
|
||||
to help alleviate some of these concerns; see <xref linked="basic-jpaconvert"/>
|
||||
to help alleviate some of these concerns; see <xref linkend="basic-jpaconvert"/>
|
||||
</para>
|
||||
</tip>
|
||||
|
||||
<para>
|
||||
The <literal>@Basic</literal> annotation defines 2 attributes.
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>optional</literal> - boolean (defaults to true) - Defines whether this attribute
|
||||
allows nulls. JPA defines this as "a hint", which essentially means that it affect is
|
||||
specifically required. As long as the type is not primitive, Hibernate takes this to mean
|
||||
that the underlying column should be <literal>NULLABLE</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>fetch</literal> - FetchType (defaults to EAGER) - Defines whether this attribute
|
||||
should be fetched eagerly or lazily. JPA says that EAGER is a requirement to the provider
|
||||
(Hibernate) that the value should be fetched when the owner is fetched but that
|
||||
LAZY is merely a hint that the value be fetched when the attribute is accessed. Hibernate
|
||||
ignores this setting for basic types unless you are using bytecode enhancement. See
|
||||
the <citetitle>Hibernate User Guide</citetitle> for additional information on
|
||||
fetching and on bytecode enhancement.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>The <literal>@Column</literal> annotation</title>
|
||||
<para>
|
||||
JPA defines rules for implicitly determining the name of tables and columns. For a detailed discussion
|
||||
of implicit naming see <xref linkend="naming"/>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For basic type attributes, the implicit naming rule is that the column name is the same as the attribute
|
||||
name. If that implicit naming rule does not meet your requirements, you can explicitly tell Hibernate
|
||||
(and other providers) the column name to use.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Explicit column naming</title>
|
||||
<programlisting role="JAVA"><xi:include href="extras/ExplicitColumnNaming.java" parse="text" /></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
Here we use <literal>@Column</literal> to explicitly map the <literal>description</literal> attribute to the
|
||||
<literal>NOTES</literal> column, as opposed to the implicit column name <literal>description</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <literal>@Column</literal> annotation defines other mapping information as well. See its javadocs
|
||||
for details.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="basic-registry">
|
||||
<title>BasicTypeRegistry</title>
|
||||
<para>
|
||||
We said before that a Hibernate type is not a Java type, nor a SQL type, but that it
|
||||
understands both and performs the marshalling between them. But looking at the
|
||||
basic type mappings in the previous examples, how did Hibernate know to use
|
||||
basic type mappings from the previous examples, how did Hibernate know to use
|
||||
its <classname>org.hibernate.type.StringType</classname> for mapping for
|
||||
<classname>java.lang.String</classname> attributes or its
|
||||
<classname>org.hibernate.type.IntegerType</classname> for mapping
|
||||
|
@ -454,12 +519,12 @@
|
|||
<para>
|
||||
The answer lies in a service inside Hibernate called the
|
||||
<classname>org.hibernate.type.BasicTypeRegistry</classname>, which essentially maintains a map of
|
||||
<interface>org.hibernate.type.BasicType</interface> (a <interface>org.hibernate.type.Type</interface>
|
||||
<interfacename>org.hibernate.type.BasicType</interfacename> (a <interfacename>org.hibernate.type.Type</interfacename>
|
||||
specialization) instances keyed by a name.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
We will see later (<xref linked="basic-explicit"/>) that we can explicitly tell Hibernate which
|
||||
We will see later (<xref linkend="basic-explicit"/>) that we can explicitly tell Hibernate which
|
||||
BasicType to use for a particular attribute. But first let's explore how implicit resolution works
|
||||
and how applications can adjust implicit resolution.
|
||||
</para>
|
||||
|
@ -489,7 +554,7 @@
|
|||
Applications can also extend (add new BasicType registrations) or override (replace an exiting BasicType
|
||||
registration) using one of the <methodname>MetadataBuilder#applyBasicType</methodname> methods
|
||||
or the <methodname>MetadataBuilder#applyTypes</methodname> method during bootstrap. For more details, see
|
||||
<xref linked="basic-custom"/>
|
||||
<xref linkend="basic-custom"/>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
@ -514,20 +579,20 @@
|
|||
|
||||
<para>
|
||||
This tells Hibernate to store the Strings as nationalized data. This is just for illustration purposes;
|
||||
for better ways to indicate nationalized character data see <xref linked="basic-nationalized"/>
|
||||
for better ways to indicate nationalized character data see <xref linkend="basic-nationalized"/>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Additionally the description is to be handled as a LOB. Again, for better ways to indicate
|
||||
LOBs see <xref linked="basic-lob"/>.
|
||||
LOBs see <xref linkend="basic-lob"/>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <methodname>org.hibernate.annotations.Type#type</methodname> attribute can name any of the following:
|
||||
<itemizedlist>
|
||||
<listitem>FQN of any <interface>org.hibernate.type.Type</interface> implementation</listitem>
|
||||
<listitem>Any key registered with BasicTypeRegistry</listitem>
|
||||
<listitem>The name of any known "type definitions"</listitem>
|
||||
<listitem><para>FQN of any <interfacename>org.hibernate.type.Type</interfacename> implementation</para></listitem>
|
||||
<listitem><para>Any key registered with BasicTypeRegistry</para></listitem>
|
||||
<listitem><para>The name of any known "type definitions"</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
@ -567,44 +632,386 @@
|
|||
<programlisting role="JAVA"><xi:include href="extras/FizzywigType2_reg.java" parse="text" /></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
For additional information on developing and registering custom types, see the
|
||||
<citetitle>Hibernate Integration Guide</citetitle>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="basic-enums">
|
||||
<title>Mapping enums</title>
|
||||
|
||||
<para>
|
||||
<!-- todo : write -->
|
||||
blah blah blah
|
||||
Hibernate supports the mapping of Java enums as basic value types in a number of different ways.
|
||||
</para>
|
||||
|
||||
<section>
|
||||
<title>@Enumerated</title>
|
||||
<para>
|
||||
The original JPA-compliant way to map enums was via the <literal>@Enumerated</literal>
|
||||
and <literal>@MapKeyEnumerated</literal> for map keys annotations which works on the principle that
|
||||
the enum values are stored according to one of 2 strategies indicated by
|
||||
<interfacename>javax.persistence.EnumType</interfacename>:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>ORDINAL</literal> - stored according to the enum value's ordinal position within
|
||||
the enum class, as indicated by java.lang.Enum#ordinal
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>STRING</literal> - stored according to the enum value's name, as indicated by
|
||||
java.lang.Enum#name
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>@Enumerated(ORDINAL) example</title>
|
||||
<programlisting role="JAVA"><xi:include href="extras/EnumeratedOrdinal.java" parse="text" /></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
In the ORDINAL example, the gender column is defined as an (nullable) INTEGER type and would hold:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><literal>NULL</literal> - null</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><literal>0</literal> - MALE</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><literal>1</literal> - FEMALE</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>@Enumerated(STRING) example</title>
|
||||
<programlisting role="JAVA"><xi:include href="extras/EnumeratedString.java" parse="text" /></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
In the STRING example, the gender column is defined as an (nullable) VARCHAR type and would hold:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><literal>NULL</literal> - null</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><literal>MALE</literal> - MALE</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><literal>FEMALE</literal> - FEMALE</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>AttributeConverter</title>
|
||||
<para>
|
||||
You can also map enums in a JPA compliant way using a JPA 2.1 AttributeConverter. Let's revisit the
|
||||
Gender enum example, but instead we want to store the more standardized <literal>'M'</literal>
|
||||
and <literal>'F'</literal> codes.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Enum mapping with AttributeConverter example</title>
|
||||
<programlisting role="JAVA"><xi:include href="extras/EnumAttributeConverter.java" parse="text" /></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
Here, the gender column is defined as a CHAR type and would hold:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><literal>NULL</literal> - null</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><literal>'M'</literal> - MALE</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><literal>'F'</literal> - FEMALE</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For additional details on using AttributeConverters, see <xref linkend="basic-jpaconvert"/>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Note that JPA explicitly disallows the use of an AttributeConverter with an attribute marked
|
||||
as <literal>@Enumerated</literal>. So if using the AttributeConverter approach, be sure to not mark the
|
||||
attribute as <literal>@Enumerated</literal>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Custom type</title>
|
||||
|
||||
<para>
|
||||
You can also map enums using a Hibernate custom type mapping. Let's again revisit the Gender enum
|
||||
example, this time using a custom Type to store the more standardized <literal>'M'</literal>
|
||||
and <literal>'F'</literal> codes.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Enum mapping with custom Type example</title>
|
||||
<programlisting role="JAVA"><xi:include href="extras/EnumCustomType.java" parse="text" /></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
Again, the gender column is defined as a CHAR type and would hold:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><literal>NULL</literal> - null</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><literal>'M'</literal> - MALE</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><literal>'F'</literal> - FEMALE</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For additional details on using custom types, see <xref linkend="basic-custom"/>.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section xml:id="basic-lobs">
|
||||
<section xml:id="basic-lob">
|
||||
<title>Mapping LOBs</title>
|
||||
|
||||
<para>
|
||||
<!-- todo : write -->
|
||||
blah blah blah
|
||||
Mapping LOBs (database Large OBjects) come in 2 forms, those using the JDBC locator types and those
|
||||
<firstterm>materializing</firstterm> the LOB data.
|
||||
</para>
|
||||
|
||||
<sidebar>
|
||||
<title>Locator versus materialized</title>
|
||||
<para>
|
||||
JDBC LOB locators exist to allow efficient access to the LOB data. They allow the JDBC driver to
|
||||
stream parts of the LOB data as needed, potentially freeing up memory space. However they can be
|
||||
unnatural to deal with and have certain limitations. For example, a LOB locator is only portably
|
||||
valid during the duration of the transaction in which it was obtained.
|
||||
</para>
|
||||
<para>
|
||||
The idea of materialized LOBs is to trade-off the potential efficiency (not all drivers handle LOB
|
||||
data efficiently) for a more natural programming paradigm using familiar Java types such as
|
||||
String or byte[], etc for these LOBs.
|
||||
</para>
|
||||
<para>
|
||||
Materialized deals with the entire LOB contents in memory, whereas LOB locators (in theory) allow
|
||||
streaming parts of the LOB contents into memory as needed.
|
||||
</para>
|
||||
</sidebar>
|
||||
|
||||
<para>
|
||||
The JDBC LOB locator types include:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><interfacename>java.sql.Blob</interfacename></para>
|
||||
<para><interfacename>java.sql.Clob</interfacename></para>
|
||||
<para><interfacename>java.sql.NClob</interfacename></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Mapping materialized forms of these LOB values would use more familiar Java types
|
||||
such as String, char[], byte[], etc. The trade off for "more familiar" is usually
|
||||
performance.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For a first look lets assume we have a CLOB column that we would like to map (NCLOB character LOB data
|
||||
will be covered in <xref linkend="basic-nationalized"/>).
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>CLOB - SQL</title>
|
||||
<programlisting role="SQL"><xi:include href="extras/Clob.sql" parse="text" /></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
Let's first map this using the JDBC locator.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>CLOB - locator mapping</title>
|
||||
<programlisting role="SQL"><xi:include href="extras/ClobLocator.java" parse="text" /></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
We could also map a materialized form.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>CLOB - materialized mapping</title>
|
||||
<programlisting role="SQL"><xi:include href="extras/ClobMaterialized.java" parse="text" /></programlisting>
|
||||
</example>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
How JDBC deals with LOB data varies from driver to driver. Hibernate tries to handle all these variances
|
||||
for you. However some drivers do not allow Hibernate to always do that in an automatic fashion
|
||||
(looking directly at you PostgreSQL JDBC drivers). In such cases you may have to do some extra
|
||||
to get LOBs working. Such discussions are beyond the scope of this guide however.
|
||||
<!-- todo : document known deviations? -->
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
We might even want the materialized data as a char array (for some crazy reason).
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>CLOB - materialized char[] mapping</title>
|
||||
<programlisting role="SQL"><xi:include href="extras/ClobMaterializedCharArray.java" parse="text" /></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
We'd map BLOB data in a similar fashion.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>BLOB - SQL</title>
|
||||
<programlisting role="SQL"><xi:include href="extras/Blob.sql" parse="text" /></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
Let's first map this using the JDBC locator.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>BLOB - locator mapping</title>
|
||||
<programlisting role="SQL"><xi:include href="extras/BlobLocator.java" parse="text" /></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
We could also map a materialized BLOB form.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>BLOB - materialized mapping</title>
|
||||
<programlisting role="SQL"><xi:include href="extras/BlobMaterialized.java" parse="text" /></programlisting>
|
||||
</example>
|
||||
|
||||
<!-- todo : alternatives : text, image -->
|
||||
</section>
|
||||
|
||||
<section xml:id="basic-nationalized">
|
||||
<title>Mapping Nationalized Character Data</title>
|
||||
|
||||
<para>
|
||||
<!-- todo : write -->
|
||||
blah blah blah
|
||||
JDBC 4 added the ability to explicitly handle nationalized character data. To this end
|
||||
it added specific nationalized character data types.
|
||||
<!-- todo : note that we saw these types above -->
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><literal>NCHAR</literal></para>
|
||||
<para><literal>NVARCHAR</literal></para>
|
||||
<para><literal>LONGNVARCHAR</literal></para>
|
||||
<para><literal>NCLOB</literal></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To map a specific attribute to a nationalized variant datatype, Hibernate defines the
|
||||
<literal>@Nationalized</literal> annotation.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>NVARCHAR mapping</title>
|
||||
<programlisting role="SQL"><xi:include href="extras/NVARCHAR.java" parse="text" /></programlisting>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<title>NCLOB (locator) mapping</title>
|
||||
<programlisting role="SQL"><xi:include href="extras/NCLOB_locator.java" parse="text" /></programlisting>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<title>NCLOB (materialized) mapping</title>
|
||||
<programlisting role="SQL"><xi:include href="extras/NCLOB_materialized.java" parse="text" /></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
If you application and database are entirely nationalized you may instead want to enable nationalized
|
||||
character data as the default. You can do this via the
|
||||
<literal>hibernate.use_nationalized_character_data</literal> setting or by calling
|
||||
<methodname>MetadataBuilder#enableGlobalNationalizedCharacterDataSupport</methodname> during bootstrap.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="basic-uuid">
|
||||
<title>Mapping UUID Values</title>
|
||||
|
||||
<para>
|
||||
<!-- todo : write -->
|
||||
blah blah blah
|
||||
Hibernate also allows you to map UUID values, again in a number of ways.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
The default UUID mapping is as binary because it represents more efficient storage. However
|
||||
many applications prefer the readability of character storage. To switch the default mapping,
|
||||
simply call <literal>MetadataBuilder.applyBasicType( UUIDCharType.INSTANCE, UUID.class.getName() )</literal>
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<section>
|
||||
<title>UUID as binary</title>
|
||||
<para>
|
||||
As mentioned, the default mapping for UUID attributes. Maps the UUID to a byte[]
|
||||
using java.util.UUID#getMostSignificantBits and java.util.UUID#getLeastSignificantBits
|
||||
and stores that as BINARY data.
|
||||
</para>
|
||||
<para>
|
||||
Chosen as the default simply because it is generally more efficient from storage perspective.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>UUID as (var)char</title>
|
||||
<para>
|
||||
Maps the UUID to a String using java.util.UUID#toString and java.util.UUID#fromString
|
||||
and stores that as CHAR or VARCHAR data.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>PostgeSQL-specific UUID</title>
|
||||
|
||||
<important>
|
||||
<para>When using one of the PostgreSQL Dialects, this becomes the default UUID mapping</para>
|
||||
</important>
|
||||
|
||||
<para>
|
||||
Maps the UUID using PostgreSQL's specific UUID data type. The PostgreSQL JDBC driver choses to
|
||||
map its UUID type to the <literal>OTHER</literal> code. Note that this can cause difficulty as the
|
||||
driver chooses to map many different data types to OTHER.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>UUID as identifier</title>
|
||||
<para>
|
||||
Hibernate supports using UUID values as identifiers. They can even be generated! For
|
||||
details see the discussion of generators in <xref linkend="identifiers"/>
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section xml:id="basic-datetime">
|
||||
<title>Mapping Date/Time Values</title>
|
||||
<para>
|
||||
<!-- todo : write -->
|
||||
<!-- todo : highly recommend java8 types (or joda time) -->
|
||||
blah blah blah
|
||||
</para>
|
||||
</section>
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
create table step(
|
||||
...
|
||||
instruction BLOB not null,
|
||||
...
|
||||
)
|
|
@ -0,0 +1,8 @@
|
|||
@Entity
|
||||
public class Step {
|
||||
...
|
||||
@Lob
|
||||
@Basic
|
||||
public Blob instructions;
|
||||
...
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
@Entity
|
||||
public class Step {
|
||||
...
|
||||
@Lob
|
||||
@Basic
|
||||
public byte[] instructions;
|
||||
...
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
create table product(
|
||||
...
|
||||
description CLOB not null,
|
||||
...
|
||||
)
|
|
@ -0,0 +1,8 @@
|
|||
@Entity
|
||||
public class Product {
|
||||
...
|
||||
@Lob
|
||||
@Basic
|
||||
public Clob description;
|
||||
...
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
@Entity
|
||||
public class Product {
|
||||
...
|
||||
@Lob
|
||||
@Basic
|
||||
public String description;
|
||||
...
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
@Entity
|
||||
public class Product {
|
||||
...
|
||||
@Lob
|
||||
@Basic
|
||||
public char[] description;
|
||||
...
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
@Entity
|
||||
public class Person {
|
||||
...
|
||||
@Basic
|
||||
@Convert( converter=GenderConverter.class )
|
||||
public Gender gender;
|
||||
}
|
||||
|
||||
public enum Gender {
|
||||
MALE( 'M' ),
|
||||
FEMALE( 'F' );
|
||||
|
||||
private final char code;
|
||||
|
||||
private Gender(char code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public char getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public static Gender fromCode(char code) {
|
||||
if ( code == 'M' || code == 'm' ) {
|
||||
return MALE;
|
||||
}
|
||||
if ( code == 'F' || code == 'f' ) {
|
||||
return FEMALE;
|
||||
}
|
||||
throw ...
|
||||
}
|
||||
}
|
||||
|
||||
@Converter
|
||||
public class GenderConverter
|
||||
implements AttributeConverter<Character,Gender> {
|
||||
|
||||
public Character convertToDatabaseColumn(Gender value) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return value.getCode();
|
||||
}
|
||||
|
||||
public Gender convertToEntityAttribute(Character value) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Gender.fromCode( value );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
import org.hibernate.type.descriptor.java.CharacterTypeDescriptor;
|
||||
|
||||
@Entity
|
||||
public class Person {
|
||||
...
|
||||
@Basic
|
||||
@Type( type = GenderType.class )
|
||||
public Gender gender;
|
||||
}
|
||||
|
||||
public enum Gender {
|
||||
MALE( 'M' ),
|
||||
FEMALE( 'F' );
|
||||
|
||||
private final char code;
|
||||
|
||||
private Gender(char code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public char getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public static Gender fromCode(char code) {
|
||||
if ( code == 'M' || code == 'm' ) {
|
||||
return MALE;
|
||||
}
|
||||
if ( code == 'F' || code == 'f' ) {
|
||||
return FEMALE;
|
||||
}
|
||||
throw ...
|
||||
}
|
||||
}
|
||||
|
||||
@Converter
|
||||
public class GenderType
|
||||
extends AbstractSingleColumnStandardBasicType<Gender> {
|
||||
|
||||
public static final GenderType INSTANCE = new GenderType();
|
||||
|
||||
private GenderType() {
|
||||
super(
|
||||
CharTypeDescriptor.INSTANCE,
|
||||
GenderJavaTypeDescriptor.INSTANCE
|
||||
);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "gender";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean registerUnderJavaType() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class GenderJavaTypeDescriptor
|
||||
extends AbstractTypeDescriptor<Gender> {
|
||||
public static final GenderJavaTypeDescriptor INSTANCE = new GenderJavaTypeDescriptor();
|
||||
|
||||
public String toString(Gender value) {
|
||||
return value == null ? null : value.name();
|
||||
}
|
||||
|
||||
public Gender fromString(String string) {
|
||||
return string == null ? null : Gender.valueOf( string );
|
||||
}
|
||||
|
||||
public <X> X unwrap(Gender value, Class<X> type, WrapperOptions options) {
|
||||
return CharacterTypeDescriptor.INSTANCE.unwrap(
|
||||
value == null ? null : value.getCode(),
|
||||
type,
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
public <X> Gender wrap(X value, WrapperOptions options) {
|
||||
return CharacterTypeDescriptor.INSTANCE.wrap( value, options );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
@Entity
|
||||
public class Person {
|
||||
...
|
||||
@Enumerated
|
||||
public Gender gender;
|
||||
|
||||
public static enum Gender {
|
||||
MALE,
|
||||
FEMALE
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
@Entity
|
||||
public class Person {
|
||||
...
|
||||
@Enumerated(STRING)
|
||||
public Gender gender;
|
||||
|
||||
public static enum Gender {
|
||||
MALE,
|
||||
FEMALE
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
@Entity
|
||||
public class Product {
|
||||
@Id
|
||||
@Basic
|
||||
private Integer id;
|
||||
@Basic
|
||||
private String sku;
|
||||
@Basic
|
||||
private String name;
|
||||
@Basic
|
||||
@Column( name = "NOTES" )
|
||||
private String description;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
@Entity
|
||||
public class Product {
|
||||
...
|
||||
@Lob
|
||||
@Basic
|
||||
@Nationalized
|
||||
public NClob description;
|
||||
// Clob also works, because NClob
|
||||
// extends Clob. The db type is
|
||||
// still NCLOB either way and
|
||||
// handled as such
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
@Entity
|
||||
public class Product {
|
||||
...
|
||||
@Lob
|
||||
@Basic
|
||||
@Nationalized
|
||||
public String description;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
@Entity
|
||||
public class Product {
|
||||
...
|
||||
@Basic
|
||||
@Nationalized
|
||||
public String description;
|
||||
...
|
||||
}
|
|
@ -73,7 +73,7 @@
|
|||
<title>Bags</title>
|
||||
<para>
|
||||
<!-- todo : discuss mapping bags -->
|
||||
todo : discuss mapping bags
|
||||
todo : discuss mapping bags and idbags
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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>.
|
||||
-->
|
||||
<chapter xml:id="entity"
|
||||
version="5.0"
|
||||
xml:lang="en"
|
||||
xmlns="http://docbook.org/ns/docbook"
|
||||
>
|
||||
<title>Entity</title>
|
||||
<para>
|
||||
* POJO, etc discussion from manual/en-US/chapters/domain/DomainModel.xml
|
||||
* dynamic models (hbm.xml)
|
||||
* Map mode
|
||||
* proxy solutions (hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer2)
|
||||
* inheritance
|
||||
* optimistic locking
|
||||
</para>
|
||||
</chapter>
|
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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>.
|
||||
-->
|
||||
<chapter xml:id="identifiers"
|
||||
version="5.0"
|
||||
xml:lang="en"
|
||||
xmlns="http://docbook.org/ns/docbook"
|
||||
>
|
||||
<title>Identifiers</title>
|
||||
|
||||
<para>
|
||||
Identifiers model the primary key of an entity. They are used to uniquely identify each
|
||||
specific entity. Every entity must define an identifier.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Technically the identifier does not have to map to the column(s) physically defined as the entity
|
||||
table's primary key. They just need to map to column(s) that uniquely identify each row. However
|
||||
this documentation will continue to use the terms identifier and primary key interchangeably.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
An identifier might be simple (single value) or composite (multiple values).
|
||||
</para>
|
||||
|
||||
<!-- todo : be sure to discuss generators in simple, then reference from composite -->
|
||||
|
||||
<section>
|
||||
<title>Simple identifiers</title>
|
||||
<para></para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Composite identifiers</title>
|
||||
<para></para>
|
||||
|
||||
<section>
|
||||
<title>Composite identifiers - aggregated</title>
|
||||
<para></para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Composite identifiers - non-aggregated</title>
|
||||
<para></para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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>.
|
||||
-->
|
||||
<chapter xml:id="naturalid"
|
||||
version="5.0"
|
||||
xml:lang="en"
|
||||
xmlns="http://docbook.org/ns/docbook"
|
||||
>
|
||||
<title>Natural Ids</title>
|
||||
<para>
|
||||
* simple
|
||||
* composite
|
||||
* caching
|
||||
* apis
|
||||
</para>
|
||||
</chapter>
|
|
@ -308,6 +308,17 @@ public interface MetadataBuilder {
|
|||
*/
|
||||
MetadataBuilder applyBasicType(BasicType type);
|
||||
|
||||
/**
|
||||
* Specify an additional or overridden basic type mapping supplying specific
|
||||
* registration keys.
|
||||
*
|
||||
* @param type The type addition or override.
|
||||
* @param keys The keys under which to register the basic type.
|
||||
*
|
||||
* @return {@code this}, for method chaining
|
||||
*/
|
||||
MetadataBuilder applyBasicType(BasicType type, String... keys);
|
||||
|
||||
/**
|
||||
* Register an additional or overridden custom type mapping.
|
||||
*
|
||||
|
@ -316,7 +327,7 @@ public interface MetadataBuilder {
|
|||
*
|
||||
* @return {@code this}, for method chaining
|
||||
*/
|
||||
MetadataBuilder applyBasicType(UserType type, String[] keys);
|
||||
MetadataBuilder applyBasicType(UserType type, String... keys);
|
||||
|
||||
/**
|
||||
* Register an additional or overridden composite custom type mapping.
|
||||
|
@ -326,7 +337,7 @@ public interface MetadataBuilder {
|
|||
*
|
||||
* @return {@code this}, for method chaining
|
||||
*/
|
||||
MetadataBuilder applyBasicType(CompositeUserType type, String[] keys);
|
||||
MetadataBuilder applyBasicType(CompositeUserType type, String... keys);
|
||||
|
||||
/**
|
||||
* Apply an explicit TypeContributor (implicit application via ServiceLoader will still happen too)
|
||||
|
|
|
@ -12,7 +12,6 @@ import java.util.Collections;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.SharedCacheMode;
|
||||
|
||||
|
@ -50,6 +49,7 @@ import org.hibernate.boot.registry.StandardServiceRegistry;
|
|||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
||||
import org.hibernate.boot.spi.BasicTypeRegistration;
|
||||
import org.hibernate.boot.spi.JpaOrmXmlPersistenceUnitDefaultAware;
|
||||
import org.hibernate.boot.spi.MappingDefaults;
|
||||
import org.hibernate.boot.spi.MetadataBuilderImplementor;
|
||||
|
@ -72,10 +72,9 @@ import org.hibernate.internal.util.StringHelper;
|
|||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.CompositeCustomType;
|
||||
import org.hibernate.type.CustomType;
|
||||
import org.hibernate.usertype.CompositeUserType;
|
||||
import org.hibernate.usertype.UserType;
|
||||
|
||||
import org.jboss.jandex.IndexView;
|
||||
|
||||
import static org.hibernate.internal.log.DeprecationLogger.DEPRECATION_LOGGER;
|
||||
|
@ -252,19 +251,25 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
|||
|
||||
@Override
|
||||
public MetadataBuilder applyBasicType(BasicType type) {
|
||||
options.basicTypeRegistrations.add( type );
|
||||
options.basicTypeRegistrations.add( new BasicTypeRegistration( type ) );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataBuilder applyBasicType(UserType type, String[] keys) {
|
||||
options.basicTypeRegistrations.add( new CustomType( type, keys ) );
|
||||
public MetadataBuilder applyBasicType(BasicType type, String... keys) {
|
||||
options.basicTypeRegistrations.add( new BasicTypeRegistration( type, keys ) );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataBuilder applyBasicType(CompositeUserType type, String[] keys) {
|
||||
options.basicTypeRegistrations.add( new CompositeCustomType( type, keys ) );
|
||||
public MetadataBuilder applyBasicType(UserType type, String... keys) {
|
||||
options.basicTypeRegistrations.add( new BasicTypeRegistration( type, keys ) );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataBuilder applyBasicType(CompositeUserType type, String... keys) {
|
||||
options.basicTypeRegistrations.add( new BasicTypeRegistration( type, keys ) );
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -276,17 +281,22 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
|||
|
||||
@Override
|
||||
public void contributeType(BasicType type) {
|
||||
options.basicTypeRegistrations.add( type );
|
||||
options.basicTypeRegistrations.add( new BasicTypeRegistration( type ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contributeType(BasicType type, String... keys) {
|
||||
options.basicTypeRegistrations.add( new BasicTypeRegistration( type, keys ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contributeType(UserType type, String[] keys) {
|
||||
options.basicTypeRegistrations.add( new CustomType( type, keys ) );
|
||||
options.basicTypeRegistrations.add( new BasicTypeRegistration( type, keys ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contributeType(CompositeUserType type, String[] keys) {
|
||||
options.basicTypeRegistrations.add( new CompositeCustomType( type, keys ) );
|
||||
options.basicTypeRegistrations.add( new BasicTypeRegistration( type, keys ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -523,7 +533,7 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
|||
private final StandardServiceRegistry serviceRegistry;
|
||||
private final MappingDefaultsImpl mappingDefaults;
|
||||
|
||||
private ArrayList<BasicType> basicTypeRegistrations = new ArrayList<BasicType>();
|
||||
private ArrayList<BasicTypeRegistration> basicTypeRegistrations = new ArrayList<BasicTypeRegistration>();
|
||||
|
||||
private IndexView jandexView;
|
||||
private ClassLoader tempClassLoader;
|
||||
|
@ -747,7 +757,7 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<BasicType> getBasicTypeRegistrations() {
|
||||
public List<BasicTypeRegistration> getBasicTypeRegistrations() {
|
||||
return basicTypeRegistrations;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,9 +16,11 @@ import org.hibernate.usertype.UserType;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface TypeContributions {
|
||||
public void contributeType(BasicType type);
|
||||
void contributeType(BasicType type);
|
||||
|
||||
public void contributeType(UserType type, String... keys);
|
||||
void contributeType(BasicType type, String... keys);
|
||||
|
||||
public void contributeType(CompositeUserType type, String... keys);
|
||||
void contributeType(UserType type, String... keys);
|
||||
|
||||
void contributeType(CompositeUserType type, String... keys);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.hibernate.boot.model.source.internal.hbm.ModelBinder;
|
|||
import org.hibernate.boot.model.source.spi.MetadataSourceProcessor;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.boot.spi.AdditionalJaxbMappingProducer;
|
||||
import org.hibernate.boot.spi.BasicTypeRegistration;
|
||||
import org.hibernate.boot.spi.ClassLoaderAccess;
|
||||
import org.hibernate.boot.spi.MetadataBuildingOptions;
|
||||
import org.hibernate.boot.spi.MetadataContributor;
|
||||
|
@ -36,6 +37,7 @@ import org.hibernate.cfg.AttributeConverterDefinition;
|
|||
import org.hibernate.cfg.MetadataSourceType;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.BasicTypeRegistry;
|
||||
import org.hibernate.type.TypeFactory;
|
||||
import org.hibernate.type.TypeResolver;
|
||||
|
@ -330,6 +332,11 @@ public class MetadataBuildingProcess {
|
|||
basicTypeRegistry.register( type );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contributeType(BasicType type, String... keys) {
|
||||
basicTypeRegistry.register( type, keys );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contributeType(UserType type, String[] keys) {
|
||||
basicTypeRegistry.register( type, keys );
|
||||
|
@ -351,8 +358,11 @@ public class MetadataBuildingProcess {
|
|||
}
|
||||
|
||||
// add explicit application registered types
|
||||
for ( org.hibernate.type.BasicType basicType : options.getBasicTypeRegistrations() ) {
|
||||
basicTypeRegistry.register( basicType );
|
||||
for ( BasicTypeRegistration basicTypeRegistration : options.getBasicTypeRegistrations() ) {
|
||||
basicTypeRegistry.register(
|
||||
basicTypeRegistration.getBasicType(),
|
||||
basicTypeRegistration.getRegistrationKeys()
|
||||
);
|
||||
}
|
||||
|
||||
return basicTypeRegistry;
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.hibernate.dialect.function.SQLFunction;
|
|||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.usertype.CompositeUserType;
|
||||
import org.hibernate.usertype.UserType;
|
||||
|
||||
import org.jboss.jandex.IndexView;
|
||||
|
||||
/**
|
||||
|
@ -38,6 +39,7 @@ import org.jboss.jandex.IndexView;
|
|||
* @param <T> The type of a specific sub-class; Allows sub-classes to narrow down the return-type of the contract methods
|
||||
* to a specialization of {@link MetadataBuilderImplementor}
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class AbstractDelegatingMetadataBuilderImplementor<T extends AbstractDelegatingMetadataBuilderImplementor<T>> implements MetadataBuilderImplementor {
|
||||
|
||||
private final MetadataBuilderImplementor delegate;
|
||||
|
@ -166,13 +168,19 @@ public abstract class AbstractDelegatingMetadataBuilderImplementor<T extends Abs
|
|||
}
|
||||
|
||||
@Override
|
||||
public MetadataBuilder applyBasicType(UserType type, String[] keys) {
|
||||
public MetadataBuilder applyBasicType(BasicType type, String... keys) {
|
||||
delegate.applyBasicType( type, keys );
|
||||
return getThis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataBuilder applyBasicType(CompositeUserType type, String[] keys) {
|
||||
public MetadataBuilder applyBasicType(UserType type, String... keys) {
|
||||
delegate.applyBasicType( type, keys );
|
||||
return getThis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataBuilder applyBasicType(CompositeUserType type, String... keys) {
|
||||
delegate.applyBasicType( type, keys );
|
||||
return getThis();
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ package org.hibernate.boot.spi;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.SharedCacheMode;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
@ -27,7 +26,7 @@ import org.hibernate.cache.spi.access.AccessType;
|
|||
import org.hibernate.cfg.AttributeConverterDefinition;
|
||||
import org.hibernate.cfg.MetadataSourceType;
|
||||
import org.hibernate.dialect.function.SQLFunction;
|
||||
import org.hibernate.type.BasicType;
|
||||
|
||||
import org.jboss.jandex.IndexView;
|
||||
|
||||
/**
|
||||
|
@ -56,7 +55,7 @@ public abstract class AbstractDelegatingMetadataBuildingOptions implements Metad
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<BasicType> getBasicTypeRegistrations() {
|
||||
public List<BasicTypeRegistration> getBasicTypeRegistrations() {
|
||||
return delegate.getBasicTypeRegistrations();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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.boot.spi;
|
||||
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.CompositeCustomType;
|
||||
import org.hibernate.type.CustomType;
|
||||
import org.hibernate.usertype.CompositeUserType;
|
||||
import org.hibernate.usertype.UserType;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class BasicTypeRegistration {
|
||||
private final BasicType basicType;
|
||||
private final String[] registrationKeys;
|
||||
|
||||
public BasicTypeRegistration(BasicType basicType) {
|
||||
this( basicType, basicType.getRegistrationKeys() );
|
||||
}
|
||||
|
||||
public BasicTypeRegistration(BasicType basicType, String[] registrationKeys) {
|
||||
this.basicType = basicType;
|
||||
this.registrationKeys = registrationKeys;
|
||||
}
|
||||
|
||||
public BasicTypeRegistration(UserType type, String[] keys) {
|
||||
this( new CustomType( type, keys ), keys );
|
||||
}
|
||||
|
||||
public BasicTypeRegistration(CompositeUserType type, String[] keys) {
|
||||
this( new CompositeCustomType( type, keys ), keys );
|
||||
}
|
||||
|
||||
public BasicType getBasicType() {
|
||||
return basicType;
|
||||
}
|
||||
|
||||
public String[] getRegistrationKeys() {
|
||||
return registrationKeys;
|
||||
}
|
||||
}
|
|
@ -25,7 +25,6 @@ import org.hibernate.cache.spi.access.AccessType;
|
|||
import org.hibernate.cfg.AttributeConverterDefinition;
|
||||
import org.hibernate.cfg.MetadataSourceType;
|
||||
import org.hibernate.dialect.function.SQLFunction;
|
||||
import org.hibernate.type.BasicType;
|
||||
|
||||
import org.jboss.jandex.IndexView;
|
||||
|
||||
|
@ -56,13 +55,14 @@ public interface MetadataBuildingOptions {
|
|||
* Access the list of BasicType registrations. These are the BasicTypes explicitly
|
||||
* registered via calls to:<ul>
|
||||
* <li>{@link org.hibernate.boot.MetadataBuilder#applyBasicType(org.hibernate.type.BasicType)}</li>
|
||||
* <li>{@link org.hibernate.boot.MetadataBuilder#applyBasicType(org.hibernate.type.BasicType, String[])}</li>
|
||||
* <li>{@link org.hibernate.boot.MetadataBuilder#applyBasicType(org.hibernate.usertype.UserType, java.lang.String[])}</li>
|
||||
* <li>{@link org.hibernate.boot.MetadataBuilder#applyBasicType(org.hibernate.usertype.CompositeUserType, java.lang.String[])}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return The BasicType registrations
|
||||
*/
|
||||
List<BasicType> getBasicTypeRegistrations();
|
||||
List<BasicTypeRegistration> getBasicTypeRegistrations();
|
||||
|
||||
/**
|
||||
* Access to the Jandex index passed by call to
|
||||
|
|
|
@ -110,6 +110,10 @@ public class BasicTypeRegistry implements Serializable {
|
|||
}
|
||||
|
||||
public void register(BasicType type) {
|
||||
register( type, type.getRegistrationKeys() );
|
||||
}
|
||||
|
||||
public void register(BasicType type, String[] keys) {
|
||||
if ( locked ) {
|
||||
throw new HibernateException( "Can not alter TypeRegistry at this time" );
|
||||
}
|
||||
|
@ -118,11 +122,12 @@ public class BasicTypeRegistry implements Serializable {
|
|||
throw new HibernateException( "Type to register cannot be null" );
|
||||
}
|
||||
|
||||
if ( type.getRegistrationKeys() == null || type.getRegistrationKeys().length == 0 ) {
|
||||
if ( keys == null || keys.length == 0 ) {
|
||||
LOG.typeDefinedNoRegistrationKeys( type );
|
||||
return;
|
||||
}
|
||||
|
||||
for ( String key : type.getRegistrationKeys() ) {
|
||||
for ( String key : keys ) {
|
||||
// be safe...
|
||||
if ( key == null ) {
|
||||
continue;
|
||||
|
|
Loading…
Reference in New Issue