HHH-11186 - Add examples for all Hibernate annotations
Document @TableGenerator
This commit is contained in:
parent
e10653e3a7
commit
5e23b7fd02
|
@ -588,7 +588,7 @@ See the <<chapters/query/native/Native.adoc#sql-custom-crud-secondary-table-exam
|
|||
|
||||
The http://docs.oracle.com/javaee/7/api/javax/persistence/TableGenerator.html[`@TableGenerator`] annotation is used to specify the database table used by the identity generator of the current annotated entity.
|
||||
|
||||
//TODO: Add example
|
||||
See the <<chapters/domain/identifiers.adoc#identifiers-generators-table-configured-mapping-example,`@TableGenerator` mapping>> section for more info.
|
||||
|
||||
[[annotations-jpa-temporal]]
|
||||
==== `@Temporal`
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
create table hibernate_sequences(
|
||||
sequence_name VARCHAR NOT NULL,
|
||||
next_val INTEGER NOT NULL
|
||||
)
|
|
@ -1,9 +0,0 @@
|
|||
@Entity
|
||||
public class MyEntity {
|
||||
|
||||
@Id
|
||||
@GeneratedValue( generation = TABLE )
|
||||
public Integer id;
|
||||
|
||||
...
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
create table table_identifier (
|
||||
table_name varchar2(255 char) not null,
|
||||
product_id number(19,0),
|
||||
primary key (table_name)
|
||||
)
|
|
@ -0,0 +1,78 @@
|
|||
select
|
||||
tbl.product_id
|
||||
from
|
||||
table_identifier tbl
|
||||
where
|
||||
tbl.table_name = ?
|
||||
for update
|
||||
|
||||
-- binding parameter [1] - [Product]
|
||||
|
||||
insert
|
||||
into
|
||||
table_identifier
|
||||
(table_name, product_id)
|
||||
values
|
||||
(?, ?)
|
||||
|
||||
-- binding parameter [1] - [Product]
|
||||
-- binding parameter [2] - [1]
|
||||
|
||||
update
|
||||
table_identifier
|
||||
set
|
||||
product_id= ?
|
||||
where
|
||||
product_id= ?
|
||||
and table_name= ?
|
||||
|
||||
-- binding parameter [1] - [6]
|
||||
-- binding parameter [2] - [1]
|
||||
|
||||
select
|
||||
tbl.product_id
|
||||
from
|
||||
table_identifier tbl
|
||||
where
|
||||
tbl.table_name= ? for update
|
||||
|
||||
update
|
||||
table_identifier
|
||||
set
|
||||
product_id= ?
|
||||
where
|
||||
product_id= ?
|
||||
and table_name= ?
|
||||
|
||||
-- binding parameter [1] - [11]
|
||||
-- binding parameter [2] - [6]
|
||||
|
||||
insert
|
||||
into
|
||||
Product
|
||||
(product_name, id)
|
||||
values
|
||||
(?, ?)
|
||||
|
||||
-- binding parameter [1] as [VARCHAR] - [Product 1]
|
||||
-- binding parameter [2] as [BIGINT] - [1]
|
||||
|
||||
insert
|
||||
into
|
||||
Product
|
||||
(product_name, id)
|
||||
values
|
||||
(?, ?)
|
||||
|
||||
-- binding parameter [1] as [VARCHAR] - [Product 2]
|
||||
-- binding parameter [2] as [BIGINT] - [2]
|
||||
|
||||
insert
|
||||
into
|
||||
Product
|
||||
(product_name, id)
|
||||
values
|
||||
(?, ?)
|
||||
|
||||
-- binding parameter [1] as [VARCHAR] - [Product 3]
|
||||
-- binding parameter [2] as [BIGINT] - [3]
|
|
@ -0,0 +1,5 @@
|
|||
create table hibernate_sequences (
|
||||
sequence_name varchar2(255 char) not null,
|
||||
next_val number(19,0),
|
||||
primary key (sequence_name)
|
||||
)
|
|
@ -261,7 +261,7 @@ The simplest form is to simply request sequence generation; Hibernate will use a
|
|||
====
|
||||
[source,java]
|
||||
----
|
||||
include::{sourcedir}/UnnamedSequenceTest.java[tag=identifiers-generators-sequence-mapping-example, indent=0]
|
||||
include::{sourcedir}/SequenceGeneratorUnnamedTest.java[tag=identifiers-generators-sequence-mapping-example, indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
|
@ -272,7 +272,7 @@ Using `javax.persistence.SequenceGenerator`, you can specify a specific database
|
|||
====
|
||||
[source,java]
|
||||
----
|
||||
include::{sourcedir}/NamedSequenceTest.java[tag=identifiers-generators-sequence-mapping-example, indent=0]
|
||||
include::{sourcedir}/SequenceGeneratorNamedTest.java[tag=identifiers-generators-sequence-mapping-example, indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
|
@ -283,7 +283,7 @@ The `javax.persistence.SequenceGenerator` annotataion allows you to specify addi
|
|||
====
|
||||
[source,java]
|
||||
----
|
||||
include::{sourcedir}/ConfiguredSequenceTest.java[tag=identifiers-generators-sequence-mapping-example, indent=0]
|
||||
include::{sourcedir}/SequenceGeneratorConfiguredTest.java[tag=identifiers-generators-sequence-mapping-example, indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
|
@ -313,30 +313,63 @@ If the application is not usually creating many new instances of a given type of
|
|||
====
|
||||
|
||||
[[identifiers-generators-table]]
|
||||
==== Using identifier table
|
||||
==== Using table identifier generator
|
||||
|
||||
Hibernate achieves table-based identifier generation based on its `org.hibernate.id.enhanced.TableGenerator` id generator which defines a table capable of holding multiple named value segments for any number of entities.
|
||||
Hibernate achieves table-based identifier generation based on its `org.hibernate.id.enhanced.TableGenerator` which defines a table capable of holding multiple named value segments for any number of entities.
|
||||
|
||||
.Table generator table structure
|
||||
====
|
||||
[source,sql]
|
||||
----
|
||||
include::{extrasdir}/id/TableGenerator.sql[]
|
||||
----
|
||||
====
|
||||
|
||||
The basic idea is that a given table-generator table (`hibernate_sequences` for example) can hold multiple segments of identifier generation values.
|
||||
|
||||
[[identifiers-generators-table-unnamed-mapping-example]]
|
||||
.Unnamed table generator
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
include::{extrasdir}/id/UnnamedTable.java[]
|
||||
include::{sourcedir}/TableGeneratorUnnamedTest.java[tag=identifiers-generators-table-mapping-example, indent=0]
|
||||
----
|
||||
|
||||
[source,sql]
|
||||
----
|
||||
include::{extrasdir}/id/identifiers-generators-table-unnamed-mapping-example.sql[]
|
||||
----
|
||||
====
|
||||
|
||||
If no table name is given Hibernate assumes an implicit name of `hibernate_sequences`.
|
||||
Additionally, because no `javax.persistence.TableGenerator#pkColumnValue` is specified, Hibernate will use the default segment (`sequence_name='default'`) from the hibernate_sequences table.
|
||||
|
||||
Additionally, because no `javax.persistence.TableGenerator#pkColumnValue` is specified,
|
||||
Hibernate will use the default segment (`sequence_name='default'`) from the hibernate_sequences table.
|
||||
|
||||
However, you can configure the table identifier generator using the http://docs.oracle.com/javaee/7/api/javax/persistence/TableGenerator.html[`@TableGenerator`] annotation.
|
||||
|
||||
[[identifiers-generators-table-configured-mapping-example]]
|
||||
.Configured table generator
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
include::{sourcedir}/TableGeneratorConfiguredTest.java[tag=identifiers-generators-table-mapping-example, indent=0]
|
||||
----
|
||||
|
||||
[source,sql]
|
||||
----
|
||||
include::{extrasdir}/id/identifiers-generators-table-configured-mapping-example.sql[]
|
||||
----
|
||||
====
|
||||
|
||||
Now, when inserting 3 `Product` entities, Hibernate generates the following statements:
|
||||
|
||||
[[identifiers-generators-table-configured-persist-example]]]
|
||||
.Configured table generator persist example
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
include::{sourcedir}/TableGeneratorConfiguredTest.java[tag=identifiers-generators-table-persist-example, indent=0]
|
||||
----
|
||||
|
||||
[source,sql]
|
||||
----
|
||||
include::{extrasdir}/id/identifiers-generators-table-configured-persist-example.sql[]
|
||||
----
|
||||
====
|
||||
|
||||
[[identifiers-generators-uuid]]
|
||||
==== Using UUID generation
|
||||
|
|
|
@ -25,7 +25,7 @@ import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
|||
* @author Vlad Mihalcea
|
||||
*/
|
||||
@RequiresDialectFeature(DialectChecks.SupportsSequences.class)
|
||||
public class ConfiguredSequenceTest extends BaseEntityManagerFunctionalTestCase {
|
||||
public class SequenceGeneratorConfiguredTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
|
@ -27,7 +27,7 @@ import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
|||
* @author Vlad Mihalcea
|
||||
*/
|
||||
@RequiresDialectFeature(DialectChecks.SupportsSequences.class)
|
||||
public class NamedSequenceTest extends BaseEntityManagerFunctionalTestCase {
|
||||
public class SequenceGeneratorNamedTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
|
@ -24,7 +24,7 @@ import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
|||
* @author Vlad Mihalcea
|
||||
*/
|
||||
@RequiresDialectFeature(DialectChecks.SupportsSequences.class)
|
||||
public class UnnamedSequenceTest extends BaseEntityManagerFunctionalTestCase {
|
||||
public class SequenceGeneratorUnnamedTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* 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.mapping.identifier;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.TableGenerator;
|
||||
|
||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
public class TableGeneratorConfiguredTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
Product.class
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
//tag::identifiers-generators-table-persist-example[]
|
||||
for ( long i = 1; i <= 3; i++ ) {
|
||||
Product product = new Product();
|
||||
product.setName( String.format( "Product %d", i ) );
|
||||
entityManager.persist( product );
|
||||
}
|
||||
//end::identifiers-generators-table-persist-example[]
|
||||
} );
|
||||
}
|
||||
|
||||
//tag::identifiers-generators-table-mapping-example[]
|
||||
@Entity(name = "Product")
|
||||
public static class Product {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(
|
||||
strategy = GenerationType.TABLE,
|
||||
generator = "table-generator"
|
||||
)
|
||||
@TableGenerator(
|
||||
name = "table-generator",
|
||||
table = "table_identifier",
|
||||
pkColumnName = "table_name",
|
||||
valueColumnName = "product_id",
|
||||
allocationSize = 5
|
||||
)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "product_name")
|
||||
private String name;
|
||||
|
||||
//Getters and setters are omitted for brevity
|
||||
|
||||
//end::identifiers-generators-table-mapping-example[]
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
//tag::identifiers-generators-table-mapping-example[]
|
||||
}
|
||||
//end::identifiers-generators-table-mapping-example[]
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* 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.mapping.identifier;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||
|
||||
import org.hibernate.testing.DialectChecks;
|
||||
import org.hibernate.testing.RequiresDialectFeature;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
public class TableGeneratorUnnamedTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
Product.class
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
for ( long i = 1; i <= 5; i++ ) {
|
||||
if(i % 3 == 0) {
|
||||
entityManager.flush();
|
||||
}
|
||||
Product product = new Product();
|
||||
product.setName( String.format( "Product %d", i ) );
|
||||
entityManager.persist( product );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
//tag::identifiers-generators-table-mapping-example[]
|
||||
@Entity(name = "Product")
|
||||
public static class Product {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(
|
||||
strategy = GenerationType.TABLE
|
||||
)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "product_name")
|
||||
private String name;
|
||||
|
||||
//Getters and setters are omitted for brevity
|
||||
|
||||
//end::identifiers-generators-table-mapping-example[]
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
//tag::identifiers-generators-table-mapping-example[]
|
||||
}
|
||||
//end::identifiers-generators-table-mapping-example[]
|
||||
}
|
|
@ -27,6 +27,8 @@ log4j.logger.org.hibernate.SQL=debug
|
|||
### log JDBC bind parameters ###
|
||||
log4j.logger.org.hibernate.type=trace
|
||||
log4j.logger.org.hibernate.type.descriptor.sql=trace
|
||||
log4j.logger.org.hibernate.id.enhanced.TableGenerator=trace
|
||||
log4j.logger.org.hibernate.id.IdentifierGeneratorHelper=trace
|
||||
log4j.logger.org.hibernate.persister.entity.AbstractEntityPersister=trace
|
||||
log4j.logger.org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl=trace
|
||||
|
||||
|
|
|
@ -306,6 +306,7 @@ public final class IdentifierGeneratorHelper {
|
|||
|
||||
public void bind(PreparedStatement preparedStatement, int position) throws SQLException {
|
||||
// TODO : bind it as 'exact type'? Not sure if that gains us anything...
|
||||
LOG.tracef( "binding parameter [%s] - [%s]", position, value );
|
||||
preparedStatement.setLong( position, value );
|
||||
}
|
||||
|
||||
|
|
|
@ -544,6 +544,7 @@ public class TableGenerator implements PersistentIdentifierGenerator, Configurab
|
|||
|
||||
final PreparedStatement insertPS = prepareStatement( connection, insertQuery, statementLogger, statsCollector );
|
||||
try {
|
||||
LOG.tracef( "binding parameter [%s] - [%s]", 1, segmentValue );
|
||||
insertPS.setString( 1, segmentValue );
|
||||
value.bind( insertPS, 2 );
|
||||
executeUpdate( insertPS, statsCollector );
|
||||
|
|
Loading…
Reference in New Issue