column lengths and LOBs
This commit is contained in:
parent
a92f29f802
commit
0ed12f6869
|
@ -226,6 +226,7 @@ With rare exception, the default behavior of every one of these settings was car
|
||||||
The properties you really do need to get started are these three:
|
The properties you really do need to get started are these three:
|
||||||
|
|
||||||
.JDBC connection settings
|
.JDBC connection settings
|
||||||
|
[cols=",2"]
|
||||||
|===
|
|===
|
||||||
| Configuration property name | Purpose
|
| Configuration property name | Purpose
|
||||||
|
|
||||||
|
@ -255,6 +256,7 @@ This pool is not meant for use in production, and later, when we discuss perform
|
||||||
Alternatively, in a container environment, you'll need at least one of these properties:
|
Alternatively, in a container environment, you'll need at least one of these properties:
|
||||||
|
|
||||||
.Transaction management settings
|
.Transaction management settings
|
||||||
|
[cols=",2"]
|
||||||
|===
|
|===
|
||||||
| Configuration property name | Purpose
|
| Configuration property name | Purpose
|
||||||
|
|
||||||
|
@ -276,7 +278,7 @@ initialization time by specifying one or more of the following configuration
|
||||||
properties:
|
properties:
|
||||||
|
|
||||||
.Schema management settings
|
.Schema management settings
|
||||||
[cols="1,1"]
|
[cols=",2"]
|
||||||
|===
|
|===
|
||||||
| Configuration property name | Purpose
|
| Configuration property name | Purpose
|
||||||
|
|
||||||
|
@ -339,6 +341,7 @@ logger.hibernate.level = debug
|
||||||
You can make the logged SQL more readable by enabling one or both of the following settings:
|
You can make the logged SQL more readable by enabling one or both of the following settings:
|
||||||
|
|
||||||
.Setting for SQL logging to the console
|
.Setting for SQL logging to the console
|
||||||
|
[cols=",2"]
|
||||||
|===
|
|===
|
||||||
| Configuration property name | Purpose
|
| Configuration property name | Purpose
|
||||||
|
|
||||||
|
@ -353,6 +356,7 @@ These settings can really help when troubleshooting SQL.
|
||||||
The following properties are very useful for minimizing the amount of information you'll need to explicitly specify in `@Table` and `@Column` annotations, which we'll discuss below in <<mapping-entity-classes>>:
|
The following properties are very useful for minimizing the amount of information you'll need to explicitly specify in `@Table` and `@Column` annotations, which we'll discuss below in <<mapping-entity-classes>>:
|
||||||
|
|
||||||
.Settings for minimizing explicit mapping information
|
.Settings for minimizing explicit mapping information
|
||||||
|
[cols=",2"]
|
||||||
|===
|
|===
|
||||||
| Configuration property name | Purpose
|
| Configuration property name | Purpose
|
||||||
|
|
||||||
|
@ -376,7 +380,8 @@ Please refer to the Javadoc for these interfaces for more information about the
|
||||||
|
|
||||||
_By default,_ SQL Server's `char` and `varchar` types don't accommodate Unicode data. So, if you're working with SQL Server, you might need to force Hibernate to use the `nchar` and `nvarchar` types.
|
_By default,_ SQL Server's `char` and `varchar` types don't accommodate Unicode data. So, if you're working with SQL Server, you might need to force Hibernate to use the `nchar` and `nvarchar` types.
|
||||||
|
|
||||||
.Setting the use of nationalized charcter data
|
.Setting the use of nationalized character data
|
||||||
|
[cols=",2"]
|
||||||
|===
|
|===
|
||||||
| Configuration property name | Purpose
|
| Configuration property name | Purpose
|
||||||
|
|
||||||
|
|
|
@ -208,6 +208,7 @@ On the other hand, if, as is more common, you're working with a pre-existing dat
|
||||||
JPA defines the following strategies for generating ids, which are enumerated by `GenerationType`:
|
JPA defines the following strategies for generating ids, which are enumerated by `GenerationType`:
|
||||||
|
|
||||||
.Standard id generation strategies
|
.Standard id generation strategies
|
||||||
|
[cols="3,2,6"]
|
||||||
|===
|
|===
|
||||||
| Strategy | Java type | Implementation
|
| Strategy | Java type | Implementation
|
||||||
|
|
||||||
|
@ -215,7 +216,7 @@ JPA defines the following strategies for generating ids, which are enumerated by
|
||||||
| `GenerationType.IDENTITY` | `Long` or `Integer` | An identity or autoincrement column.
|
| `GenerationType.IDENTITY` | `Long` or `Integer` | An identity or autoincrement column.
|
||||||
| `GenerationType.SEQUENCE` | `Long` or `Integer` | A database sequence.
|
| `GenerationType.SEQUENCE` | `Long` or `Integer` | A database sequence.
|
||||||
| `GenerationType.TABLE` | `Long` or `Integer` | A database table.
|
| `GenerationType.TABLE` | `Long` or `Integer` | A database table.
|
||||||
| `GenerationType.AUTO` | `Long` or `Integer` | Selects `SEQUENCE` `TABLE`, or `UUID` based on the identifier type and capabilities of the database.
|
| `GenerationType.AUTO` | `Long` or `Integer` | Selects `SEQUENCE`, `TABLE`, or `UUID` based on the identifier type and capabilities of the database.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
For example, the following id maps to a SQL `identity`, `auto_increment`, or `bigserial` column:
|
For example, the following id maps to a SQL `identity`, `auto_increment`, or `bigserial` column:
|
||||||
|
@ -447,6 +448,7 @@ A _basic_ attribute of an entity is a field or property which maps to a single c
|
||||||
The JPA specification defines a quite limited set of basic types:
|
The JPA specification defines a quite limited set of basic types:
|
||||||
|
|
||||||
.JPA-standard basic attribute types
|
.JPA-standard basic attribute types
|
||||||
|
[cols="3,2,6"]
|
||||||
|====
|
|====
|
||||||
| Classification | Package | Types
|
| Classification | Package | Types
|
||||||
|
|
||||||
|
@ -476,6 +478,17 @@ Serializing a Java object and storing its binary representation in the database
|
||||||
As we'll soon see in <<embeddable-objects>>, Hibernate has much better ways to handle complex Java objects.
|
As we'll soon see in <<embeddable-objects>>, Hibernate has much better ways to handle complex Java objects.
|
||||||
====
|
====
|
||||||
|
|
||||||
|
Hibernate slightly extends this list with the following types:
|
||||||
|
|
||||||
|
.Additional basic attribute types in Hibernate
|
||||||
|
[cols="3,2,6"]
|
||||||
|
|====
|
||||||
|
| Classification | Package | Types
|
||||||
|
|
||||||
|
| Date/time types | `java.time` | `Duration`, `ZoneId`, `ZoneOffset`, `ZonedDateTime`, `Year`
|
||||||
|
| Miscellaneous | `java.util` | `Currency`, `URL`
|
||||||
|
|====
|
||||||
|
|
||||||
The `@Basic` annotation explicitly specifies that an attribute is basic, but it's often not needed, since attributes are assumed basic by default.
|
The `@Basic` annotation explicitly specifies that an attribute is basic, but it's often not needed, since attributes are assumed basic by default.
|
||||||
On the other hand, if an attribute cannot be null, use of `@Basic(optional=false)` is highly recommended.
|
On the other hand, if an attribute cannot be null, use of `@Basic(optional=false)` is highly recommended.
|
||||||
|
|
||||||
|
@ -1203,18 +1216,18 @@ Let's pause to remember the annotations we've met so far.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
.Declaring basic attributes
|
.Declaring basic attributes
|
||||||
[cols="2,4,1"]
|
[cols="2,4,2,1"]
|
||||||
|===
|
|===
|
||||||
| Annotation | Purpose | JPA-standard
|
| Annotation | Purpose | Required | JPA-standard
|
||||||
|
|
||||||
| `@Id` | Declare a basic-typed identifier attribute | ✓
|
| `@Id` | Declare a basic-typed identifier attribute | Yes | ✓
|
||||||
| `@Version` | Declare a version attribute | ✓
|
| `@Version` | Declare a version attribute | Yes | ✓
|
||||||
| `@Basic` | (Optional) Declare a basic attribute | ✓
|
| `@Basic` | Declare a basic attribute | No | ✓
|
||||||
| `@EmbeddedId` | Declare an embeddable-typed identifier attribute | ✓
|
| `@EmbeddedId` | Declare an embeddable-typed identifier attribute | Yes | ✓
|
||||||
| `@Embedded` | (Optional) Declare an embeddable-typed attribute | ✓
|
| `@Embedded` | Declare an embeddable-typed attribute | No | ✓
|
||||||
| `@Enumerated` | (Optional) Declare an `enum`-typed attribute and specify how it is encoded | ✓
|
| `@Enumerated` | Declare an `enum`-typed attribute and specify how it is encoded | No | ✓
|
||||||
| `@Array` | (Optional) Declare that an attribute maps to a SQL `ARRAY`, and specify the length | ✗
|
| `@Array` | Declare that an attribute maps to a SQL `ARRAY`, and specify the length | No | ✗
|
||||||
| `@ElementCollection` | Declare that a collection is mapped to a dedicated table | ✓
|
| `@ElementCollection` | Declare that a collection is mapped to a dedicated table | Yes | ✓
|
||||||
|===
|
|===
|
||||||
|
|
||||||
.Converters and compositional basic types
|
.Converters and compositional basic types
|
||||||
|
|
|
@ -156,6 +156,7 @@ is a bad idea, since it's impossible to create a foreign key constraint that tar
|
||||||
The following annotations specify exactly how elements of the domain model map to tables of the relational model:
|
The following annotations specify exactly how elements of the domain model map to tables of the relational model:
|
||||||
|
|
||||||
.Annotations for mapping tables
|
.Annotations for mapping tables
|
||||||
|
[cols=",5"]
|
||||||
|===
|
|===
|
||||||
| Annotation | Purpose
|
| Annotation | Purpose
|
||||||
|
|
||||||
|
@ -187,6 +188,7 @@ class Book { ... }
|
||||||
The `@Table` annotation can do more than just specify a name:
|
The `@Table` annotation can do more than just specify a name:
|
||||||
|
|
||||||
.`@Table` annotation members
|
.`@Table` annotation members
|
||||||
|
[cols=",8"]
|
||||||
|===
|
|===
|
||||||
| Annotation member | Purpose
|
| Annotation member | Purpose
|
||||||
|
|
||||||
|
@ -208,6 +210,7 @@ It's usually better to set the configuration properties `hibernate.default_schem
|
||||||
The `@SecondaryTable` annotation is even more interesting:
|
The `@SecondaryTable` annotation is even more interesting:
|
||||||
|
|
||||||
.`@SecondaryTable` annotation members
|
.`@SecondaryTable` annotation members
|
||||||
|
[cols=",8"]
|
||||||
|===
|
|===
|
||||||
| Annotation member | Purpose
|
| Annotation member | Purpose
|
||||||
|
|
||||||
|
@ -228,6 +231,7 @@ To understand this annotation better, we must first discuss column mappings in g
|
||||||
These annotations specify how elements of the domain model map to columns of tables in the relational model:
|
These annotations specify how elements of the domain model map to columns of tables in the relational model:
|
||||||
|
|
||||||
.Annotations for mapping columns
|
.Annotations for mapping columns
|
||||||
|
[cols=",5"]
|
||||||
|===
|
|===
|
||||||
| Annotation | Purpose
|
| Annotation | Purpose
|
||||||
|
|
||||||
|
@ -246,6 +250,7 @@ We use the `@Column` annotation to map basic attributes.
|
||||||
The `@Column` annotation is not only useful for specifying the column name.
|
The `@Column` annotation is not only useful for specifying the column name.
|
||||||
|
|
||||||
.`@Column` annotation members
|
.`@Column` annotation members
|
||||||
|
[cols=",8"]
|
||||||
|===
|
|===
|
||||||
| Annotation member | Purpose
|
| Annotation member | Purpose
|
||||||
|
|
||||||
|
@ -299,6 +304,7 @@ We don't use `@Column` to map associations.
|
||||||
The `@JoinColumn` annotation is used to customize a foreign key column.
|
The `@JoinColumn` annotation is used to customize a foreign key column.
|
||||||
|
|
||||||
.`@JoinColumn` annotation members
|
.`@JoinColumn` annotation members
|
||||||
|
[cols=",8"]
|
||||||
|===
|
|===
|
||||||
| Annotation member | Purpose
|
| Annotation member | Purpose
|
||||||
|
|
||||||
|
@ -346,6 +352,7 @@ The `@PrimaryKeyJoinColumn` is a special-purpose annotation for mapping:
|
||||||
- the primary key column of the primary table mapped by a subclass in a `JOINED` inheritance hierarchy—which is also a foreign key referencing the primary table mapped by the root entity.
|
- the primary key column of the primary table mapped by a subclass in a `JOINED` inheritance hierarchy—which is also a foreign key referencing the primary table mapped by the root entity.
|
||||||
|
|
||||||
.`@PrimaryKeyJoinColumn` annotation members
|
.`@PrimaryKeyJoinColumn` annotation members
|
||||||
|
[cols=",8"]
|
||||||
|===
|
|===
|
||||||
| Annotation member | Purpose
|
| Annotation member | Purpose
|
||||||
|
|
||||||
|
@ -387,3 +394,73 @@ class Book {
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
|
[[column-lengths]]
|
||||||
|
=== Column lengths and adaptive column types
|
||||||
|
|
||||||
|
Hibernate automatically adjusts the column type used in generated DDL based on the column length specified by the `@Column` annotation.
|
||||||
|
So we don't usually need to explicitly specify that a column should be of type `TEXT` or `CLOB`—or worry about the parade of `TINYTEXT`, `MEDIUMTEXT`, `TEXT`, `LONGTEXT` types on MySQL—because Hibernate will automatically select one of those types if required to accommodate a string of the `length` we specify.
|
||||||
|
|
||||||
|
The constant values defined in the class `org.hibernate.Length` are very helpful here:
|
||||||
|
|
||||||
|
.Predefined column lengths
|
||||||
|
[cols=",,8"]
|
||||||
|
|===
|
||||||
|
| Constant | Value | Description
|
||||||
|
|
||||||
|
| `DEFAULT` | 255 | The default length of a `VARCHAR` or `VARBINARY` column when none is explicitly specified
|
||||||
|
| `LONG` | 32600 | The largest column length for a `VARCHAR` or `VARBINARY` that is allowed on every database Hibernate supports
|
||||||
|
| `LONG16` | 32767 | The maximum length that can be represented using 16 bits (but this length is too large for a `VARCHAR` or `VARBINARY` column on for some database)
|
||||||
|
| `LONG32` | 2147483647 | The maximum length for a Java string
|
||||||
|
|===
|
||||||
|
|
||||||
|
We can use these constants in the `@Column` annotation:
|
||||||
|
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
@Column(length=LONG)
|
||||||
|
String text;
|
||||||
|
|
||||||
|
@Column(length=LONG32)
|
||||||
|
byte[] binaryData;
|
||||||
|
----
|
||||||
|
|
||||||
|
This is usually all you need to do to make use of large object types in Hibernate.
|
||||||
|
|
||||||
|
[[lobs]]
|
||||||
|
=== LOBs
|
||||||
|
|
||||||
|
JPA provides a `@Lob` annotation which specifies that a field should be persisted as a `BLOB` or `CLOB`.
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
.Semantics of the `@Lob` amnotation
|
||||||
|
====
|
||||||
|
What the spec actually says is that the field should be persisted
|
||||||
|
|
||||||
|
> as a large object to a database-supported large object type.
|
||||||
|
|
||||||
|
It's quite unclear what this means, and the spec goes on to say that
|
||||||
|
|
||||||
|
> the treatment of the `Lob` annotation is provider-dependent
|
||||||
|
|
||||||
|
which doesn't help much.
|
||||||
|
====
|
||||||
|
|
||||||
|
Hibernate interprets this annotation in what we think is the most reasonable way.
|
||||||
|
In Hibernate, an attribute annotated `@Lob` will be written to JDBC using the `setClob()` or `setBlob()` method of `PreparedStatement`, and will be read from JDBC using the `getClob()` or `getBlob()` method of `ResultSet`.
|
||||||
|
|
||||||
|
Now, the use of these JDBC methods is usually unnecessary!
|
||||||
|
JDBC drivers are perfectly capable of converting between `String` and `CLOB` or between `byte[]` and `BLOB`.
|
||||||
|
So unless you specifically need to use these JDBC LOB APIs, you _don't_ need the `@Lob` annotation.
|
||||||
|
|
||||||
|
Instead, as we just saw in <<column-lengths>>, all you need is to specify a large enough column `length` to accommodate the data you plan to write to that column.
|
||||||
|
|
||||||
|
[WARNING]
|
||||||
|
.PostgreSQL `BYTEA` and `TEXT`
|
||||||
|
====
|
||||||
|
Unfortunately, the driver for PostgreSQL does not allow `BYTEA` or `TEXT` columns to be read via the JDBC LOB APIs.
|
||||||
|
|
||||||
|
This limitation of the Postgres driver has resulted in a whole cottage industry of bloggers and stackoverflow question-answerers recommending convoluted ways to hack the Hibernate `Dialect` for Postgres to allow an attribute annotated `@Lob` to be written using `setString()` and read using `getString()`.
|
||||||
|
|
||||||
|
But _simply removing the `@Lob` annotation has exactly the same effect!_
|
||||||
|
====
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue