2020-06-28

Hibernate JPA @Nationalized Example

@Nationalized

The @Nationalized annotation is used to specify that the currently annotated attribute is a character type (e.g. String, Character, Clob) that is stored in a nationalized column type (NVARCHAR, NCHAR, NCLOB).

Nationalized

Marks a character data type (String, Character, character, Clob) as being a nationalized variant (NVARCHAR, NCHAR, NCLOB, etc).

Mapping Nationalized Character Data

JDBC 4 added the ability to explicitly handle nationalized character data. To this end, it added specific nationalized character data types:

NCHAR

NVARCHAR

LONGNVARCHAR

NCLOB

Considering we have the following database table:

Example 46. NVARCHAR - SQL
CREATE TABLE Product (
    id INTEGER NOT NULL ,
    name VARCHAR(255) ,
    warranty NVARCHAR(255) ,
    PRIMARY KEY ( id )
)
To map a specific attribute to a nationalized variant data type, Hibernate defines the @Nationalized annotation.

Example : NVARCHAR mapping

@Entity(name = "Product")
public static class Product {

    @Id
    private Integer id;

    private String name;

    @Nationalized
    private String warranty;

    //Getters and setters are omitted for brevity

}
Just like with CLOB, Hibernate can also deal with NCLOB SQL data types:

Example : NCLOB - SQL

CREATE TABLE Product (
    id INTEGER NOT NULL ,
    name VARCHAR(255) ,
    warranty nclob ,
    PRIMARY KEY ( id )
)
Hibernate can map the NCLOB to a java.sql.NClob

Example : NCLOB mapped to java.sql.NClob

@Entity(name = "Product")
public static class Product {

    @Id
    private Integer id;

    private String name;

    @Lob
    @Nationalized
    // Clob also works, because NClob extends Clob.
    // The database type is still NCLOB either way and handled as such.
    private NClob warranty;

    //Getters and setters are omitted for brevity

}
To persist such an entity, you have to create an NClob using the NClobProxy Hibernate utility:

Example : Persisting a java.sql.NClob entity

String warranty = "My product warranty";

final Product product = new Product();
product.setId( 1 );
product.setName( "Mobile phone" );

product.setWarranty( NClobProxy.generateProxy( warranty ) );

entityManager.persist( product );
To retrieve the NClob content, you need to transform the underlying java.io.Reader:

Example 51. Returning a java.sql.NClob entity
Product product = entityManager.find( Product.class, productId );

try (Reader reader = product.getWarranty().getCharacterStream()) {
    assertEquals( "My product warranty", toString( reader ) );
}
We could also map the NCLOB in a materialized form. This way, we can either use a String or a char[].

Example : NCLOB mapped to String

@Entity(name = "Product")
public static class Product {

    @Id
    private Integer id;

    private String name;

    @Lob
    @Nationalized
    private String warranty;

    //Getters and setters are omitted for brevity

}
We might even want the materialized data as a char array.

Example : NCLOB - materialized char[] mapping

@Entity(name = "Product")
public static class Product {

    @Id
    private Integer id;

    private String name;

    @Lob
    @Nationalized
    private char[] warranty;

    //Getters and setters are omitted for brevity

}

No comments:

Post a Comment