Convert basic chapter examples to unit tests for quoting, column transformers, and @Any mappings
This commit is contained in:
parent
fc24cdb708
commit
68af365916
|
@ -1015,20 +1015,27 @@ You can force Hibernate to quote an identifier in the generated SQL by enclosing
|
|||
Hibernate will use the correct quotation style for the SQL `Dialect`.
|
||||
This is usually double quotes, but the SQL Server uses brackets and MySQL uses backticks.
|
||||
|
||||
[[basic-quoting-example]]
|
||||
.Quoting column names
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
@Entity @Table(name="`Line Item`")
|
||||
class LineItem {
|
||||
include::{sourcedir}/basic/QuotingTest.java[tags=basic-quoting-example]
|
||||
----
|
||||
====
|
||||
|
||||
@Id
|
||||
@Column(name="`Item Id`")
|
||||
private Integer id;
|
||||
Because `name` and `number` are reserved words, the `Product` entity mapping uses backtricks to quote these column names.
|
||||
|
||||
@Column(name="`Item #`")
|
||||
private Integer itemNumber
|
||||
}
|
||||
When saving teh following `Product entity`, Hibernate generates the following SQL insert statement:
|
||||
|
||||
[[basic-quoting-persistence-example]]
|
||||
.Persisting a quoted column name
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/basic/QuotingTest.java[tags=basic-quoting-persistence-example, indent=0]
|
||||
|
||||
include::{extrasdir}/basic/basic-quoting-persistence-example.sql[indent=0]
|
||||
----
|
||||
====
|
||||
|
||||
|
@ -1115,25 +1122,14 @@ As you can see, the `new Date()` object value was used for assigning the `timest
|
|||
==== Column transformers: read and write expressions
|
||||
|
||||
Hibernate allows you to customize the SQL it uses to read and write the values of columns mapped to `@Basic` types.
|
||||
For example, if your database provides a set of data encryption functions, you can invoke them for individual columns like this:
|
||||
For example, if your database provides a set of data encryption functions, you can invoke them for individual columns like in the following example.
|
||||
|
||||
[[mapping-column-read-and-write-example]]
|
||||
.`@ColumnTransformer` example
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
@Entity
|
||||
class CreditCard {
|
||||
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
@Column(name="credit_card_num")
|
||||
@ColumnTransformer(
|
||||
read="decrypt(credit_card_num)",
|
||||
write="encrypt(?)"
|
||||
)
|
||||
private String creditCardNumber;
|
||||
}
|
||||
include::{sourcedir}/../fetching/FetchingTest.java[tags=mapping-column-read-and-write-example]
|
||||
----
|
||||
====
|
||||
|
||||
|
@ -1144,28 +1140,12 @@ You can use the plural form `@ColumnTransformers` if more than one columns need
|
|||
|
||||
If a property uses more than one column, you must use the `forColumn` attribute to specify which column, the expressions are targeting.
|
||||
|
||||
[[mapping-column-read-and-write-composite-type-example]]
|
||||
.`@ColumnTransformer` `forColumn` attribute usage
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
@Entity
|
||||
class User {
|
||||
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
@Type(type="com.acme.type.CreditCardType")
|
||||
@Columns( {
|
||||
@Column(name="credit_card_num"),
|
||||
@Column(name="exp_date")
|
||||
})
|
||||
@ColumnTransformer(
|
||||
forColumn="credit_card_num",
|
||||
read="decrypt(credit_card_num)",
|
||||
write="encrypt(?)"
|
||||
)
|
||||
private CreditCard creditCard;
|
||||
}
|
||||
include::{sourcedir}/basic/ColumnTransformerTest.java[tags=mapping-column-read-and-write-composite-type-example]
|
||||
----
|
||||
====
|
||||
|
||||
|
@ -1177,18 +1157,48 @@ This functionality is similar to a derived-property <<mapping-column-formula>> w
|
|||
|
||||
The `write` expression, if specified, must contain exactly one '?' placeholder for the value.
|
||||
|
||||
[[mapping-column-read-and-write-composite-type-persistence-example]]
|
||||
.Persisting an entity with a `@ColumnTransformer` and a composite type
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/basic/ColumnTransformerTest.java[tags=mapping-column-read-and-write-composite-type-persistence-example]
|
||||
----
|
||||
|
||||
[source, SQL, indent=0]
|
||||
----
|
||||
include::{extrasdir}/basic/mapping-column-read-and-write-composite-type-persistence-example.sql[]
|
||||
----
|
||||
====
|
||||
|
||||
[[mapping-column-formula]]
|
||||
==== Formula
|
||||
|
||||
Sometimes, you want the Database to do some computation for you rather than in the JVM, you might also create some kind of virtual column.
|
||||
You can use a SQL fragment (aka formula) instead of mapping a property into a column. This kind of property is read only (its value is calculated by your formula fragment)
|
||||
|
||||
[[mapping-column-formula-example]]
|
||||
.`@Formula` mapping usage
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
@Formula("obj_length * obj_height * obj_width")
|
||||
private long objectVolume;
|
||||
include::{sourcedir}/basic/FormulaTest.java[tags=mapping-column-formula-example]
|
||||
----
|
||||
====
|
||||
|
||||
When loading the `Account` entity, Hibernate is going to calculate the `interest` property using the configured `@Formula`:
|
||||
|
||||
[[mapping-column-formula-persistence-example]]
|
||||
.Persisting an entity with a `@Formula` mapping
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/basic/FormulaTest.java[tags=mapping-column-formula-persistence-example]
|
||||
----
|
||||
|
||||
[source, SQL, indent=0]
|
||||
----
|
||||
include::{extrasdir}/basic/mapping-column-formula-persistence-example.sql[]
|
||||
----
|
||||
====
|
||||
|
||||
|
@ -1198,7 +1208,7 @@ The SQL fragment can be as complex as you want and even include subselects.
|
|||
====
|
||||
|
||||
[[mapping-column-any]]
|
||||
==== Any
|
||||
==== @Any mapping
|
||||
|
||||
There is one more type of property mapping.
|
||||
The `@Any` mapping defines a polymorphic association to classes from multiple tables.
|
||||
|
@ -1215,54 +1225,116 @@ This is not the usual way of mapping polymorphic associations and you should use
|
|||
The `@Any` annotation describes the column holding the metadata information.
|
||||
To link the value of the metadata information and an actual entity type, the `@AnyDef` and `@AnyDefs` annotations are used.
|
||||
The `metaType` attribute allows the application to specify a custom type that maps database column values to persistent classes that have identifier properties of the type specified by `idType`.
|
||||
You must specify the mapping from values of the metaType to class names.
|
||||
You must specify the mapping from values of the `metaType` to class names.
|
||||
|
||||
For the next examples, consider the following `Property` class hierarchy:
|
||||
|
||||
[[mapping-column-any-property-example]]
|
||||
.`Property` class hierarchy
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/basic/any/Property.java[tags=mapping-column-any-property-example]
|
||||
|
||||
include::{sourcedir}/basic/any/IntegerProperty.java[tags=mapping-column-any-property-example]
|
||||
|
||||
include::{sourcedir}/basic/any/StringProperty.java[tags=mapping-column-any-property-example]
|
||||
----
|
||||
====
|
||||
|
||||
A `PropertyHolder` can reference any such property, and, because each `Property` belongs to a separate table, the `@Any` annotation is, therefore, required.
|
||||
|
||||
[[mapping-column-any-example]]
|
||||
.`@Any` mapping usage
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
@Any(
|
||||
metaColumn = @Column( name = "property_type" ),
|
||||
fetch=FetchType.EAGER
|
||||
)
|
||||
@AnyMetaDef(
|
||||
idType = "integer",
|
||||
metaType = "string",
|
||||
metaValues = {
|
||||
@MetaValue( value = "S", targetEntity = StringProperty.class ),
|
||||
@MetaValue( value = "I", targetEntity = IntegerProperty.class )
|
||||
}
|
||||
)
|
||||
@JoinColumn( name = "property_id" )
|
||||
private Property mainProperty;
|
||||
include::{sourcedir}/basic/any/PropertyHolder.java[tags=mapping-column-any-example]
|
||||
----
|
||||
|
||||
[source, SQL, indent=0]
|
||||
----
|
||||
include::{extrasdir}/basic/mapping-column-any-example.sql[]
|
||||
----
|
||||
====
|
||||
|
||||
Note that `@AnyDef` can be mutualized and reused. It is recommended to place it as a package metadata in this case.
|
||||
As you can see, there are two columns used to reference a `Property` instance: `property_id` and `property_type`.
|
||||
The `property_id` is used to match the `id` column of either the `string_property` or `integer_property` tables,
|
||||
while the `property_type` is used to match the `string_property` or the `integer_property` table.
|
||||
|
||||
.`@AnyMetaDef` mapping usage
|
||||
The table resolving mapping is defined by the `metaDef` attribute which references an `@AnyMetaDef` mapping.
|
||||
Although the `@AnyMetaDef` mapping could be set right next to the `@Any` annotation,
|
||||
it's good practice to reuse it, therefore it makes sense to configure it on a class or package-level basis.
|
||||
|
||||
The `package-info.java` contains the `@AnyMetaDef` mapping:
|
||||
|
||||
[[mapping-column-any-meta-def-example]]
|
||||
.`@Any` mapping usage
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
//on a package
|
||||
@AnyMetaDef( name="property"
|
||||
idType = "integer",
|
||||
metaType = "string",
|
||||
metaValues = {
|
||||
@MetaValue( value = "S", targetEntity = StringProperty.class ),
|
||||
@MetaValue( value = "I", targetEntity = IntegerProperty.class )
|
||||
}
|
||||
)
|
||||
package org.hibernate.test.annotations.any;
|
||||
|
||||
//in a class
|
||||
@Any(
|
||||
metaDef="property",
|
||||
metaColumn = @Column( name = "property_type" ),
|
||||
fetch=FetchType.EAGER
|
||||
)
|
||||
@JoinColumn( name = "property_id" )
|
||||
private Property mainProperty;
|
||||
include::{sourcedir}/basic/any/package-info.java[tags=mapping-column-any-meta-def-example]
|
||||
----
|
||||
====
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
It is recommended to place the `@AnyMetaDef` mapping as a package metadata.
|
||||
====
|
||||
|
||||
To see how the `@Any` annotation in action, consider the following example:
|
||||
|
||||
[[mapping-column-any-persistence-example]]
|
||||
.`@Any` mapping usage
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/basic/any/AnyTest.java[tags=mapping-column-any-persistence-example]
|
||||
----
|
||||
|
||||
[source, SQL, indent=0]
|
||||
----
|
||||
include::{extrasdir}/basic/mapping-column-any-persistence-example.sql[]
|
||||
----
|
||||
====
|
||||
|
||||
[[mapping-column-many-to-any]]
|
||||
===== `@ManyToAny` mapping
|
||||
|
||||
The `@Any` mapping is useful to emulate a `@ManyToOne` association when there can be multiple target entities.
|
||||
To emulate a `@OneToMany` association, the `@ManyToAny` annotation must be used.
|
||||
|
||||
In the following example, the `PropertyRepository` entity has a collection of `Property` entities.
|
||||
The `repository_properties` link table holds the associations between `PropertyRepository` and `Property` entities.
|
||||
|
||||
[[mapping-column-many-to-any-example]]
|
||||
.`@ManyToAny` mapping usage
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/basic/any/PropertyRepository.java[tags=mapping-column-many-to-any-example]
|
||||
----
|
||||
|
||||
[source, SQL, indent=0]
|
||||
----
|
||||
include::{extrasdir}/basic/mapping-column-many-to-any-example.sql[]
|
||||
----
|
||||
====
|
||||
|
||||
|
||||
To see how the `@ManyToAny` annotation works, consider the following example:
|
||||
|
||||
[[mapping-column-many-to-any-persistence-example]]
|
||||
.`@Any` mapping usage
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/basic/any/ManyToAnyTest.java[tags=mapping-column-many-to-any-persistence-example]
|
||||
----
|
||||
|
||||
[source, SQL, indent=0]
|
||||
----
|
||||
include::{extrasdir}/basic/mapping-column-many-to-any-persistence-example.sql[]
|
||||
----
|
||||
====
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
INSERT INTO Product ("name", "number", id)
|
||||
VALUES ('Mobile phone', '123-456-7890', 1)
|
|
@ -0,0 +1,6 @@
|
|||
CREATE TABLE property_holder (
|
||||
id BIGINT NOT NULL,
|
||||
property_type VARCHAR(255),
|
||||
property_id BIGINT,
|
||||
PRIMARY KEY ( id )
|
||||
)
|
|
@ -0,0 +1,25 @@
|
|||
INSERT INTO integer_property
|
||||
( "name", "value", id )
|
||||
VALUES ( 'age', 23, 1 )
|
||||
|
||||
INSERT INTO string_property
|
||||
( "name", "value", id )
|
||||
VALUES ( 'name', 'John Doe', 1 )
|
||||
|
||||
INSERT INTO property_holder
|
||||
( property_type, property_id, id )
|
||||
VALUES ( 'S', 1, 1 )
|
||||
|
||||
|
||||
SELECT ph.id AS id1_1_0_,
|
||||
ph.property_type AS property2_1_0_,
|
||||
ph.property_id AS property3_1_0_
|
||||
FROM property_holder ph
|
||||
WHERE ph.id = 1
|
||||
|
||||
|
||||
SELECT sp.id AS id1_2_0_,
|
||||
sp."name" AS name2_2_0_,
|
||||
sp."value" AS value3_2_0_
|
||||
FROM string_property sp
|
||||
WHERE sp.id = 1
|
|
@ -0,0 +1,12 @@
|
|||
INSERT INTO Account (credit, rate, id)
|
||||
VALUES (5000.0, 0.0125, 1)
|
||||
|
||||
SELECT
|
||||
a.id as id1_0_0_,
|
||||
a.credit as credit2_0_0_,
|
||||
a.rate as rate3_0_0_,
|
||||
a.credit * a.rate as formula0_0_
|
||||
FROM
|
||||
Account a
|
||||
WHERE
|
||||
a.id = 1
|
|
@ -0,0 +1,10 @@
|
|||
CREATE TABLE property_repository (
|
||||
id BIGINT NOT NULL,
|
||||
PRIMARY KEY ( id )
|
||||
)
|
||||
|
||||
CREATE TABLE repository_properties (
|
||||
repository_id BIGINT NOT NULL,
|
||||
property_type VARCHAR(255),
|
||||
property_id BIGINT NOT NULL
|
||||
)
|
|
@ -0,0 +1,36 @@
|
|||
INSERT INTO integer_property
|
||||
( "name", "value", id )
|
||||
VALUES ( 'age', 23, 1 )
|
||||
|
||||
INSERT INTO string_property
|
||||
( "name", "value", id )
|
||||
VALUES ( 'name', 'John Doe', 1 )
|
||||
|
||||
INSERT INTO property_repository ( id )
|
||||
VALUES ( 1 )
|
||||
|
||||
INSERT INTO repository_properties
|
||||
( repository_id , property_type , property_id )
|
||||
VALUES
|
||||
( 1 , 'I' , 1 )
|
||||
|
||||
INSERT INTO repository_properties
|
||||
( repository_id , property_type , property_id )
|
||||
VALUES
|
||||
( 1 , 'S' , 1 )
|
||||
|
||||
SELECT pr.id AS id1_1_0_
|
||||
FROM property_repository pr
|
||||
WHERE pr.id = 1
|
||||
|
||||
SELECT ip.id AS id1_0_0_ ,
|
||||
integerpro0_."name" AS name2_0_0_ ,
|
||||
integerpro0_."value" AS value3_0_0_
|
||||
FROM integer_property integerpro0_
|
||||
WHERE integerpro0_.id = 1
|
||||
|
||||
SELECT sp.id AS id1_3_0_ ,
|
||||
sp."name" AS name2_3_0_ ,
|
||||
sp."value" AS value3_3_0_
|
||||
FROM string_property sp
|
||||
WHERE sp.id = 1
|
|
@ -0,0 +1,11 @@
|
|||
INSERT INTO Savings (money, currency, id)
|
||||
VALUES (10 * 100, 'USD', 1)
|
||||
|
||||
SELECT
|
||||
s.id as id1_0_0_,
|
||||
s.money / 100 as money2_0_0_,
|
||||
s.currency as currency3_0_0_
|
||||
FROM
|
||||
Savings s
|
||||
WHERE
|
||||
s.id = 1
|
|
@ -168,6 +168,7 @@ public class FetchingTest extends BaseEntityManagerFunctionalTestCase {
|
|||
//Getters and setters omitted for brevity
|
||||
}
|
||||
|
||||
//tag::mapping-column-read-and-write-example[]
|
||||
@Entity(name = "Employee")
|
||||
public static class Employee {
|
||||
|
||||
|
@ -194,6 +195,7 @@ public class FetchingTest extends BaseEntityManagerFunctionalTestCase {
|
|||
|
||||
//Getters and setters omitted for brevity
|
||||
}
|
||||
//end::mapping-column-read-and-write-example[]
|
||||
|
||||
@Entity(name = "Project")
|
||||
public class Project {
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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.basic;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Currency;
|
||||
import java.util.Locale;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import org.hibernate.annotations.ColumnTransformer;
|
||||
import org.hibernate.annotations.Columns;
|
||||
import org.hibernate.annotations.Type;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||
|
||||
import org.hibernate.testing.RequiresDialect;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.userguide.util.TransactionUtil.doInJPA;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
@RequiresDialect(H2Dialect.class)
|
||||
public class ColumnTransformerTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
Savings.class
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLifecycle() {
|
||||
//tag::mapping-column-read-and-write-composite-type-persistence-example[]
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
//tag::basic-datetime-temporal-date-persist-example[]
|
||||
Savings savings = new Savings( );
|
||||
savings.setId( 1L );
|
||||
savings.setWallet( new MonetaryAmount( BigDecimal.TEN, Currency.getInstance( Locale.US ) ) );
|
||||
entityManager.persist( savings );
|
||||
} );
|
||||
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
Savings savings = entityManager.find( Savings.class, 1L );
|
||||
assertEquals( 10, savings.getWallet().getAmount().intValue());
|
||||
} );
|
||||
//end::mapping-column-read-and-write-composite-type-persistence-example[]
|
||||
}
|
||||
|
||||
//tag::mapping-column-read-and-write-composite-type-example[]
|
||||
@Entity(name = "Savings")
|
||||
public static class Savings {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@Type(type = "org.hibernate.userguide.mapping.basic.MonetaryAmountUserType")
|
||||
@Columns(columns = {
|
||||
@Column(name = "money"),
|
||||
@Column(name = "currency")
|
||||
})
|
||||
@ColumnTransformer(
|
||||
forColumn = "money",
|
||||
read = "money / 100",
|
||||
write = "? * 100"
|
||||
)
|
||||
private MonetaryAmount wallet;
|
||||
|
||||
//Getters and setters omitted for brevity
|
||||
|
||||
//end::mapping-column-read-and-write-composite-type-example[]
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public MonetaryAmount getWallet() {
|
||||
return wallet;
|
||||
}
|
||||
|
||||
public void setWallet(MonetaryAmount wallet) {
|
||||
this.wallet = wallet;
|
||||
}
|
||||
|
||||
|
||||
//tag::mapping-column-read-and-write-composite-type-example[]
|
||||
}
|
||||
//end::mapping-column-read-and-write-composite-type-example[]
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* 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.basic;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import org.hibernate.annotations.Formula;
|
||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.userguide.util.TransactionUtil.doInJPA;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
public class FormulaTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
Account.class
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLifecycle() {
|
||||
//tag::mapping-column-formula-persistence-example[]
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
//tag::basic-datetime-temporal-date-persist-example[]
|
||||
Account account = new Account( );
|
||||
account.setId( 1L );
|
||||
account.setCredit( 5000d );
|
||||
account.setRate( 1.25 / 100 );
|
||||
entityManager.persist( account );
|
||||
} );
|
||||
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
Account account = entityManager.find( Account.class, 1L );
|
||||
assertEquals( Double.valueOf( 62.5d ), account.getInterest());
|
||||
} );
|
||||
//end::mapping-column-formula-persistence-example[]
|
||||
}
|
||||
|
||||
//tag::mapping-column-formula-example[]
|
||||
@Entity(name = "Account")
|
||||
public static class Account {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
private Double credit;
|
||||
|
||||
private Double rate;
|
||||
|
||||
@Formula(value = "credit * rate")
|
||||
private Double interest;
|
||||
|
||||
//Getters and setters omitted for brevity
|
||||
|
||||
//end::mapping-column-formula-example[]
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Double getCredit() {
|
||||
return credit;
|
||||
}
|
||||
|
||||
public void setCredit(Double credit) {
|
||||
this.credit = credit;
|
||||
}
|
||||
|
||||
public Double getRate() {
|
||||
return rate;
|
||||
}
|
||||
|
||||
public void setRate(Double rate) {
|
||||
this.rate = rate;
|
||||
}
|
||||
|
||||
public Double getInterest() {
|
||||
return interest;
|
||||
}
|
||||
|
||||
public void setInterest(Double interest) {
|
||||
this.interest = interest;
|
||||
}
|
||||
|
||||
//tag::mapping-column-formula-example[]
|
||||
}
|
||||
//end::mapping-column-formula-example[]
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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>.
|
||||
*/
|
||||
|
||||
//$Id$
|
||||
package org.hibernate.userguide.mapping.basic;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Currency;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class MonetaryAmount implements Serializable {
|
||||
|
||||
private BigDecimal amount;
|
||||
private Currency currency;
|
||||
|
||||
public MonetaryAmount(BigDecimal amount, Currency currency) {
|
||||
this.amount = amount;
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(BigDecimal amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public Currency getCurrency() {
|
||||
return currency;
|
||||
}
|
||||
|
||||
public void setCurrency(Currency currency) {
|
||||
this.currency = currency;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* 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>.
|
||||
*/
|
||||
|
||||
//$Id$
|
||||
package org.hibernate.userguide.mapping.basic;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Currency;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.usertype.CompositeUserType;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class MonetaryAmountUserType implements CompositeUserType {
|
||||
|
||||
public String[] getPropertyNames() {
|
||||
return new String[]{"amount", "currency"};
|
||||
}
|
||||
|
||||
public Type[] getPropertyTypes() {
|
||||
return new Type[]{ StandardBasicTypes.BIG_DECIMAL, StandardBasicTypes.CURRENCY };
|
||||
}
|
||||
|
||||
public Object getPropertyValue(Object component, int property) throws HibernateException {
|
||||
MonetaryAmount ma = (MonetaryAmount) component;
|
||||
return property == 0 ? ma.getAmount() : ma.getCurrency();
|
||||
}
|
||||
|
||||
public void setPropertyValue(Object component, int property, Object value)
|
||||
throws HibernateException {
|
||||
MonetaryAmount ma = (MonetaryAmount) component;
|
||||
if ( property == 0 ) {
|
||||
ma.setAmount( (BigDecimal) value );
|
||||
}
|
||||
else {
|
||||
ma.setCurrency( (Currency) value );
|
||||
}
|
||||
}
|
||||
|
||||
public Class returnedClass() {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
public boolean equals(Object x, Object y) throws HibernateException {
|
||||
if ( x == y ) return true;
|
||||
if ( x == null || y == null ) return false;
|
||||
MonetaryAmount mx = (MonetaryAmount) x;
|
||||
MonetaryAmount my = (MonetaryAmount) y;
|
||||
return mx.getAmount().equals( my.getAmount() ) &&
|
||||
mx.getCurrency().equals( my.getCurrency() );
|
||||
}
|
||||
|
||||
public int hashCode(Object x) throws HibernateException {
|
||||
return ( (MonetaryAmount) x ).getAmount().hashCode();
|
||||
}
|
||||
|
||||
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
|
||||
throws HibernateException, SQLException {
|
||||
BigDecimal amt = StandardBasicTypes.BIG_DECIMAL.nullSafeGet( rs, names[0], session);
|
||||
Currency cur = StandardBasicTypes.CURRENCY.nullSafeGet( rs, names[1], session );
|
||||
if ( amt == null ) return null;
|
||||
return new MonetaryAmount( amt, cur );
|
||||
}
|
||||
|
||||
public void nullSafeSet(
|
||||
PreparedStatement st, Object value, int index,
|
||||
SessionImplementor session
|
||||
) throws HibernateException, SQLException {
|
||||
MonetaryAmount ma = (MonetaryAmount) value;
|
||||
BigDecimal amt = ma == null ? null : ma.getAmount();
|
||||
Currency cur = ma == null ? null : ma.getCurrency();
|
||||
StandardBasicTypes.BIG_DECIMAL.nullSafeSet( st, amt, index, session );
|
||||
StandardBasicTypes.CURRENCY.nullSafeSet( st, cur, index + 1, session );
|
||||
}
|
||||
|
||||
public Object deepCopy(Object value) throws HibernateException {
|
||||
MonetaryAmount ma = (MonetaryAmount) value;
|
||||
return new MonetaryAmount( ma.getAmount(), ma.getCurrency() );
|
||||
}
|
||||
|
||||
public boolean isMutable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Serializable disassemble(Object value, SessionImplementor session)
|
||||
throws HibernateException {
|
||||
return (Serializable) deepCopy( value );
|
||||
}
|
||||
|
||||
public Object assemble(Serializable cached, SessionImplementor session, Object owner)
|
||||
throws HibernateException {
|
||||
return deepCopy( cached );
|
||||
}
|
||||
|
||||
public Object replace(Object original, Object target, SessionImplementor session, Object owner)
|
||||
throws HibernateException {
|
||||
return deepCopy( original ); //TODO: improve
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* 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.basic;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.userguide.util.TransactionUtil.doInJPA;
|
||||
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
public class QuotingTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
Product.class
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
//tag::basic-quoting-persistence-example[]
|
||||
Product product = new Product();
|
||||
product.setId( 1L );
|
||||
product.setName( "Mobile phone" );
|
||||
product.setNumber( "123-456-7890" );
|
||||
entityManager.persist( product );
|
||||
//end::basic-quoting-persistence-example[]
|
||||
} );
|
||||
}
|
||||
|
||||
//tag::basic-quoting-example[]
|
||||
@Entity(name = "Product")
|
||||
public static class Product {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@Column(name = "`name`")
|
||||
private String name;
|
||||
|
||||
@Column(name = "`number`")
|
||||
private String number;
|
||||
|
||||
//Getters and setters are omitted for brevity
|
||||
|
||||
//end::basic-quoting-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;
|
||||
}
|
||||
|
||||
public String getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(String number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
|
||||
//tag::basic-quoting-example[]
|
||||
}
|
||||
//end::basic-quoting-example[]
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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.basic.any;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.userguide.util.TransactionUtil.doInHibernate;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
public class AnyTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
IntegerProperty.class,
|
||||
StringProperty.class,
|
||||
PropertyHolder.class
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getAnnotatedPackages() {
|
||||
return new String[] {
|
||||
getClass().getPackage().getName()
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
//tag::mapping-column-any-persistence-example[]
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
IntegerProperty ageProperty = new IntegerProperty();
|
||||
ageProperty.setId( 1L );
|
||||
ageProperty.setName( "age" );
|
||||
ageProperty.setValue( 23 );
|
||||
|
||||
StringProperty nameProperty = new StringProperty();
|
||||
nameProperty.setId( 1L );
|
||||
nameProperty.setName( "name" );
|
||||
nameProperty.setValue( "John Doe" );
|
||||
|
||||
session.persist( ageProperty );
|
||||
session.persist( nameProperty );
|
||||
|
||||
PropertyHolder namePropertyHolder = new PropertyHolder();
|
||||
namePropertyHolder.setId( 1L );
|
||||
namePropertyHolder.setProperty( nameProperty );
|
||||
session.persist( namePropertyHolder );
|
||||
} );
|
||||
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
PropertyHolder propertyHolder = session.get( PropertyHolder.class, 1L );
|
||||
assertEquals("name", propertyHolder.getProperty().getName());
|
||||
assertEquals("John Doe", propertyHolder.getProperty().getValue());
|
||||
} );
|
||||
//end::mapping-column-any-persistence-example[]
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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.basic.any;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
//tag::mapping-column-any-property-example[]
|
||||
|
||||
@Entity
|
||||
@Table(name="integer_property")
|
||||
public class IntegerProperty implements Property<Integer> {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@Column(name = "`name`")
|
||||
private String name;
|
||||
|
||||
@Column(name = "`value`")
|
||||
private Integer value;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Integer value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
//end::mapping-column-any-property-example[]
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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.basic.any;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.userguide.util.TransactionUtil.doInHibernate;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
public class ManyToAnyTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
IntegerProperty.class,
|
||||
StringProperty.class,
|
||||
PropertyRepository.class
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getAnnotatedPackages() {
|
||||
return new String[] {
|
||||
getClass().getPackage().getName()
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
//tag::mapping-column-many-to-any-persistence-example[]
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
IntegerProperty ageProperty = new IntegerProperty();
|
||||
ageProperty.setId( 1L );
|
||||
ageProperty.setName( "age" );
|
||||
ageProperty.setValue( 23 );
|
||||
|
||||
StringProperty nameProperty = new StringProperty();
|
||||
nameProperty.setId( 1L );
|
||||
nameProperty.setName( "name" );
|
||||
nameProperty.setValue( "John Doe" );
|
||||
|
||||
session.persist( ageProperty );
|
||||
session.persist( nameProperty );
|
||||
|
||||
PropertyRepository propertyRepository = new PropertyRepository();
|
||||
propertyRepository.setId( 1L );
|
||||
propertyRepository.getProperties().add( ageProperty );
|
||||
propertyRepository.getProperties().add( nameProperty );
|
||||
session.persist( propertyRepository );
|
||||
} );
|
||||
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
PropertyRepository propertyRepository = session.get( PropertyRepository.class, 1L );
|
||||
assertEquals(2, propertyRepository.getProperties().size());
|
||||
for(Property property : propertyRepository.getProperties()) {
|
||||
assertNotNull( property.getValue() );
|
||||
}
|
||||
} );
|
||||
//end::mapping-column-many-to-any-persistence-example[]
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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.basic.any;
|
||||
|
||||
//tag::mapping-column-any-property-example[]
|
||||
public interface Property<T> {
|
||||
|
||||
String getName();
|
||||
|
||||
T getValue();
|
||||
}
|
||||
//end::mapping-column-any-property-example[]
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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.basic.any;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.annotations.Any;
|
||||
|
||||
//tag::mapping-column-any-example[]
|
||||
@Entity
|
||||
@Table( name = "property_holder" )
|
||||
public class PropertyHolder {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@Any(
|
||||
metaDef = "PropertyMetaDef",
|
||||
metaColumn = @Column( name = "property_type" )
|
||||
)
|
||||
@JoinColumn( name = "property_id" )
|
||||
private Property property;
|
||||
|
||||
//Getters and setters are omitted for brevity
|
||||
|
||||
//end::mapping-column-any-example[]
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Property getProperty() {
|
||||
return property;
|
||||
}
|
||||
|
||||
public void setProperty(Property property) {
|
||||
this.property = property;
|
||||
}
|
||||
//tag::mapping-column-any-example[]
|
||||
}
|
||||
//end::mapping-column-any-example[]
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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.basic.any;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.annotations.Cascade;
|
||||
import org.hibernate.annotations.ManyToAny;
|
||||
|
||||
//tag::mapping-column-many-to-any-example[]
|
||||
@Entity
|
||||
@Table( name = "property_repository" )
|
||||
public class PropertyRepository {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@ManyToAny(
|
||||
metaDef = "PropertyMetaDef",
|
||||
metaColumn = @Column( name = "property_type" )
|
||||
)
|
||||
@Cascade( { org.hibernate.annotations.CascadeType.ALL })
|
||||
@JoinTable(name = "repository_properties",
|
||||
joinColumns = @JoinColumn(name = "repository_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "property_id")
|
||||
)
|
||||
private List<Property<?>> properties = new ArrayList<>( );
|
||||
|
||||
//Getters and setters are omitted for brevity
|
||||
|
||||
//end::mapping-column-many-to-any-example[]
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<Property<?>> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
//tag::mapping-column-many-to-any-example[]
|
||||
}
|
||||
//end::mapping-column-many-to-any-example[]
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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.basic.any;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
//tag::mapping-column-any-property-example[]
|
||||
|
||||
@Entity
|
||||
@Table(name="string_property")
|
||||
public class StringProperty implements Property<String> {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@Column(name = "`name`")
|
||||
private String name;
|
||||
|
||||
@Column(name = "`value`")
|
||||
private String value;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
//end::mapping-column-any-property-example[]
|
|
@ -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>.
|
||||
*/
|
||||
|
||||
// $Id$
|
||||
//tag::mapping-column-any-meta-def-example[]
|
||||
@AnyMetaDefs(
|
||||
@AnyMetaDef( name= "PropertyMetaDef", metaType = "string", idType = "long",
|
||||
metaValues = {
|
||||
@MetaValue(value = "S", targetEntity = StringProperty.class),
|
||||
@MetaValue(value = "I", targetEntity = IntegerProperty.class)
|
||||
}
|
||||
)
|
||||
)
|
||||
package org.hibernate.userguide.mapping.basic.any;
|
||||
|
||||
import org.hibernate.annotations.AnyMetaDef;
|
||||
import org.hibernate.annotations.AnyMetaDefs;
|
||||
import org.hibernate.annotations.MetaValue;
|
||||
//end::mapping-column-any-meta-def-example[]
|
||||
|
|
@ -4,16 +4,22 @@
|
|||
* 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>.
|
||||
*/
|
||||
|
||||
// $Id$
|
||||
@AnyMetaDefs(
|
||||
@AnyMetaDef( name= "Property", metaType = "string", idType = "integer",
|
||||
metaValues = {
|
||||
@MetaValue(value = "C", targetEntity = CharProperty.class),
|
||||
@MetaValue(value = "I", targetEntity = IntegerProperty.class),
|
||||
@MetaValue(value = "S", targetEntity = StringProperty.class),
|
||||
@MetaValue(value = "L", targetEntity = LongProperty.class)
|
||||
})
|
||||
@AnyMetaDef(
|
||||
name = "PropertyMetaDef",
|
||||
idType = "integer",
|
||||
metaType = "string",
|
||||
metaValues = {
|
||||
@MetaValue(
|
||||
value = "S",
|
||||
targetEntity = StringProperty.class
|
||||
),
|
||||
@MetaValue(
|
||||
value = "I",
|
||||
targetEntity = IntegerProperty.class
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
package org.hibernate.test.annotations.any;
|
||||
|
|
Loading…
Reference in New Issue