HHH-11290 - Migrate all documentation snippets that derive the source code from extras instead of actual Unit Tests

Fixed in the Natural Id chapter
This commit is contained in:
Vlad Mihalcea 2017-06-28 16:45:19 +03:00
parent 64b16fdf5e
commit c39a337418
15 changed files with 783 additions and 119 deletions

View File

@ -1,11 +0,0 @@
@Entity
public class Person {
@Id
private Integer id;
@NaturalId( mutable = true )
private String ssn;
...
}

View File

@ -1,16 +0,0 @@
Session session=...;
Person person = session.bySimpleNaturalId( Person.class ).load( "123-45-6789" );
person.setSsn( "987-65-4321" );
...
// returns null!
person = session.bySimpleNaturalId( Person.class )
.setSynchronizationEnabled( false )
.load( "987-65-4321" );
// returns correctly!
person = session.bySimpleNaturalId( Person.class )
.setSynchronizationEnabled( true )
.load( "987-65-4321" );

View File

@ -1,12 +0,0 @@
@Entity
@NaturalIdCache
public class Company {
@Id
private Integer id;
@NaturalId
private String taxIdentifier;
...
}

View File

@ -1,15 +0,0 @@
Session session = ...;
Company company = session.byNaturalId( Company.class )
.using( "taxIdentifier","abc-123-xyz" )
.load();
PostalCarrier carrier = session.byNaturalId( PostalCarrier.class )
.using( "postalCode",new PostalCode(... ) )
.load();
Department department = ...;
Course course = session.byNaturalId( Course.class )
.using( "department",department )
.using( "code","101" )
.load();

View File

@ -1,15 +0,0 @@
@Entity
public class Course {
@Id
private Integer id;
@NaturalId
@ManyToOne
private Department department;
@NaturalId
private String code;
...
}

View File

@ -1,11 +0,0 @@
@Entity
public class Company {
@Id
private Integer id;
@NaturalId
private String taxIdentifier;
...
}

View File

@ -1,18 +0,0 @@
@Entity
public class PostalCarrier {
@Id
private Integer id;
@NaturalId
@Embedded
private PostalCode postalCode;
...
}
@Embeddable
public class PostalCode {
...
}

View File

@ -1,7 +0,0 @@
Session session = ...;
Company company = session.bySimpleNaturalId( Company.class )
.load( "abc-123-xyz" );
PostalCarrier carrier = session.bySimpleNaturalId( PostalCarrier.class )
.load( new PostalCode(... ) );

View File

@ -1,6 +1,7 @@
[[naturalid]]
=== Natural Ids
:sourcedir: extras
:sourcedir: ../../../../../test/java/org/hibernate/userguide/mapping/identifier
:extrasdir: extras
Natural ids represent domain model unique identifiers that have a meaning in the real world too.
Even if a natural id does not make a good primary key (surrogate keys being usually preferred), it's still useful to tell Hibernate about it.
@ -9,29 +10,33 @@ As we will see later, Hibernate provides a dedicated, efficient API for loading
[[naturalid-mapping]]
==== Natural Id Mapping
Natural ids are defined in terms of one or more persistent attributes.
Natural ids are defined in terms of on
e or more persistent attributes.
[[naturalid-simple-basic-attribute-mapping-example]]
.Natural id using single basic attribute
====
[source,java]
----
include::{sourcedir}/natural_id/SimpleBasicNaturalIdMapping.java[]
include::{sourcedir}/SimpleNaturalIdTest.java[tags=naturalid-simple-basic-attribute-mapping-example,indent=0]
----
====
[[naturalid-single-embedded-attribute-mapping-example]]
.Natural id using single embedded attribute
====
[source,java]
----
include::{sourcedir}/natural_id/SimpleCompositeNaturalIdMapping.java[]
include::{sourcedir}/CompositeNaturalIdTest.java[tags=naturalid-single-embedded-attribute-mapping-example,indent=0]
----
====
[[naturalid-multiple-attribute-mapping-example]]
.Natural id using multiple persistent attributes
====
[source,java]
----
include::{sourcedir}/natural_id/NonSimpleNaturalIdMapping.java[]
include::{sourcedir}/MultipleNaturalIdTest.java[tags=naturalid-multiple-attribute-mapping-example,indent=0]
----
====
@ -46,11 +51,22 @@ This is represented by the `org.hibernate.NaturalIdLoadAccess` contract obtained
If the entity does not define a natural id, trying to load an entity by its natural id will throw an exception.
====
[[naturalid-load-access-example]]
.Using NaturalIdLoadAccess
====
[source,java]
----
include::{sourcedir}/natural_id/NaturalIdLoadAccessUsage.java[]
include::{sourcedir}/SimpleNaturalIdTest.java[tags=naturalid-load-access-example,indent=0]
----
[source,java]
----
include::{sourcedir}/CompositeNaturalIdTest.java[tags=naturalid-load-access-example,indent=0]
----
[source,java]
----
include::{sourcedir}/MultipleNaturalIdTest.java[tags=naturalid-load-access-example,indent=0]
----
====
@ -68,17 +84,26 @@ We will discuss the last method available on NaturalIdLoadAccess ( `setSynchroni
Because the `Company` and `PostalCarrier` entities define "simple" natural ids, we can load them as follows:
.Using SimpleNaturalIdLoadAccess
[[naturalid-simple-load-access-example]]
.Loading by simple natural id
====
[source,java]
----
include::{sourcedir}/natural_id/SimpleNaturalIdLoadAccessUsage.java[]
include::{sourcedir}/SimpleNaturalIdTest.java[tags=naturalid-simple-load-access-example,indent=0]
----
[source,java]
----
include::{sourcedir}/CompositeNaturalIdTest.java[tags=naturalid-simple-load-access-example,indent=0]
----
====
Here we see the use of the `org.hibernate.SimpleNaturalIdLoadAccess` contract, obtained via `Session#bySimpleNaturalId().
Here we see the use of the `org.hibernate.SimpleNaturalIdLoadAccess` contract,
obtained via `Session#bySimpleNaturalId().
`SimpleNaturalIdLoadAccess` is similar to `NaturalIdLoadAccess` except that it does not define the using method.
Instead, because these "simple" natural ids are defined based on just one attribute we can directly pass the corresponding value of that natural id attribute directly to the `load()` and `getReference()` methods.
Instead, because these _simple_ natural ids are defined based on just one attribute we can directly pass
the corresponding natural id attribute value directly to the `load()` and `getReference()` methods.
[NOTE]
====
@ -90,18 +115,21 @@ If the entity does not define a natural id, or if the natural id is not of a "si
A natural id may be mutable or immutable. By default the `@NaturalId` annotation marks an immutable natural id attribute.
An immutable natural id is expected to never change its value.
If the value(s) of the natural id attribute(s) change, `@NaturalId(mutable=true)` should be used instead.
.Mutable natural id
[[naturalid-mutable-mapping-example]]
.Mutable natural id mapping
====
[source,java]
----
include::{sourcedir}/natural_id/MutableNaturalIdMapping.java[]
include::{sourcedir}/MutableNaturalIdTest.java[tags=naturalid-mutable-mapping-example,indent=0]
----
====
Within the Session, Hibernate maintains a mapping from natural id values to entity identifiers (PK) values.
If natural ids values changed, it is possible for this mapping to become out of date until a flush occurs.
To work around this condition, Hibernate will attempt to discover any such pending changes and adjust them when the `load()` or `getReference()` methods are executed.
To be clear: this is only pertinent for mutable natural ids.
@ -112,11 +140,12 @@ If an application is certain that none of its mutable natural ids already associ
This will force Hibernate to circumvent the checking of mutable natural ids.
====
[[naturalid-mutable-synchronized-example]]
.Mutable natural id synchronization use-case
====
[source,java]
----
include::{sourcedir}/natural_id/MutableNaturalIdSynchronization.java[]
include::{sourcedir}/MutableNaturalIdTest.java[tags=naturalid-mutable-synchronized-example,indent=0]
----
====
@ -127,6 +156,6 @@ Not only can this NaturalId-to-PK resolution be cached in the Session, but we ca
====
[source,java]
----
include::{sourcedir}/natural_id/NaturalIdCaching.java[]
include::{sourcedir}/CacheableNaturalIdTest.java[tags=naturalid-cacheable-mapping-example,indent=0]
----
====

View File

@ -48,6 +48,8 @@ According to JPA, the valid types for these attributes are limited to:
* `long` or `Long`
* `java.sql.Timestamp`
However, Hibernate allows you to use even Java 8 Date/Time types, such as `Instant`.
[[locking-optimistic-version-example]]
.`@Version` annotation mapping
====

View File

@ -0,0 +1,122 @@
/*
* 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 java.util.Map;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.Session;
import org.hibernate.annotations.NaturalId;
import org.hibernate.annotations.NaturalIdCache;
import org.hibernate.cache.ehcache.EhCacheRegionFactory;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertEquals;
/**
* @author Vlad Mihalcea
*/
public class CacheableNaturalIdTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Book.class
};
}
@Override
@SuppressWarnings( "unchecked" )
protected void addConfigOptions(Map options) {
options.put( AvailableSettings.USE_SECOND_LEVEL_CACHE, Boolean.TRUE.toString() );
options.put( AvailableSettings.CACHE_REGION_FACTORY, EhCacheRegionFactory.class.getName() );
options.put( AvailableSettings.USE_QUERY_CACHE, Boolean.TRUE.toString() );
options.put( AvailableSettings.GENERATE_STATISTICS, Boolean.TRUE.toString() );
options.put( AvailableSettings.CACHE_REGION_PREFIX, "" );
}
@Test
public void test() {
doInJPA( this::entityManagerFactory, entityManager -> {
Book book = new Book();
book.setId( 1L );
book.setTitle( "High-Performance Java Persistence" );
book.setAuthor( "Vlad Mihalcea" );
book.setIsbn( "978-9730228236" );
entityManager.persist( book );
} );
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::naturalid-cacheable-load-access-example[]
Book book = entityManager
.unwrap(Session.class)
.bySimpleNaturalId( Book.class )
.load( "978-9730228236" );
//end::naturalid-cacheable-load-access-example[]
assertEquals("High-Performance Java Persistence", book.getTitle());
} );
}
//tag::naturalid-cacheable-mapping-example[]
@Entity(name = "Book")
@NaturalIdCache
public static class Book {
@Id
private Long id;
private String title;
private String author;
@NaturalId
private String isbn;
//Getters and setters are omitted for brevity
//end::naturalid-cacheable-mapping-example[]
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
//tag::naturalid-cacheable-mapping-example[]
}
//end::naturalid-cacheable-mapping-example[]
}

View File

@ -0,0 +1,193 @@
/*
* 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 java.io.Serializable;
import java.util.Objects;
import javax.persistence.Embeddable;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.Session;
import org.hibernate.annotations.NaturalId;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertEquals;
/**
* @author Vlad Mihalcea
*/
public class CompositeNaturalIdTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Book.class
};
}
@Test
public void test() {
doInJPA( this::entityManagerFactory, entityManager -> {
Book book = new Book();
book.setId( 1L );
book.setTitle( "High-Performance Java Persistence" );
book.setAuthor( "Vlad Mihalcea" );
book.setIsbn( new Isbn(
"973022823X",
"978-9730228236"
) );
entityManager.persist( book );
} );
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::naturalid-simple-load-access-example[]
Book book = entityManager
.unwrap(Session.class)
.bySimpleNaturalId( Book.class )
.load(
new Isbn(
"973022823X",
"978-9730228236"
)
);
//end::naturalid-simple-load-access-example[]
assertEquals("High-Performance Java Persistence", book.getTitle());
} );
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::naturalid-load-access-example[]
Book book = entityManager
.unwrap(Session.class)
.byNaturalId( Book.class )
.using(
"isbn",
new Isbn(
"973022823X",
"978-9730228236"
) )
.load();
//end::naturalid-load-access-example[]
assertEquals("High-Performance Java Persistence", book.getTitle());
} );
}
//tag::naturalid-single-embedded-attribute-mapping-example[]
@Entity(name = "Book")
public static class Book {
@Id
private Long id;
private String title;
private String author;
@NaturalId
@Embedded
private Isbn isbn;
//Getters and setters are omitted for brevity
//end::naturalid-single-embedded-attribute-mapping-example[]
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Isbn getIsbn() {
return isbn;
}
public void setIsbn(Isbn isbn) {
this.isbn = isbn;
}
//tag::naturalid-single-embedded-attribute-mapping-example[]
}
@Embeddable
public static class Isbn implements Serializable {
private String isbn10;
private String isbn13;
//Getters and setters are omitted for brevity
//end::naturalid-single-embedded-attribute-mapping-example[]
public Isbn() {
}
public Isbn(String isbn10, String isbn13) {
this.isbn10 = isbn10;
this.isbn13 = isbn13;
}
public String getIsbn10() {
return isbn10;
}
public void setIsbn10(String isbn10) {
this.isbn10 = isbn10;
}
public String getIsbn13() {
return isbn13;
}
public void setIsbn13(String isbn13) {
this.isbn13 = isbn13;
}
//tag::naturalid-single-embedded-attribute-mapping-example[]
@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}
Isbn isbn = (Isbn) o;
return Objects.equals( isbn10, isbn.isbn10 ) &&
Objects.equals( isbn13, isbn.isbn13 );
}
@Override
public int hashCode() {
return Objects.hash( isbn10, isbn13 );
}
}
//end::naturalid-single-embedded-attribute-mapping-example[]
}

View File

@ -0,0 +1,185 @@
/*
* 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 java.io.Serializable;
import java.util.Objects;
import javax.persistence.Embeddable;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import org.hibernate.Session;
import org.hibernate.annotations.NaturalId;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertEquals;
/**
* @author Vlad Mihalcea
*/
public class MultipleNaturalIdTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Book.class,
Publisher.class
};
}
@Test
public void test() {
doInJPA( this::entityManagerFactory, entityManager -> {
Publisher publisher = new Publisher();
publisher.setId( 1L );
publisher.setName( "Amazon" );
entityManager.persist( publisher );
Book book = new Book();
book.setId( 1L );
book.setTitle( "High-Performance Java Persistence" );
book.setAuthor( "Vlad Mihalcea" );
book.setProductNumber( "973022823X" );
book.setPublisher( publisher );
entityManager.persist( book );
} );
doInJPA( this::entityManagerFactory, entityManager -> {
Publisher publisher = entityManager.getReference( Publisher.class, 1L );
//tag::naturalid-load-access-example[]
Book book = entityManager
.unwrap(Session.class)
.byNaturalId( Book.class )
.using("productNumber", "973022823X")
.using("publisher", publisher)
.load();
//end::naturalid-load-access-example[]
assertEquals("High-Performance Java Persistence", book.getTitle());
} );
}
//tag::naturalid-multiple-attribute-mapping-example[]
@Entity(name = "Book")
public static class Book {
@Id
private Long id;
private String title;
private String author;
@NaturalId
private String productNumber;
@NaturalId
@ManyToOne(fetch = FetchType.LAZY)
private Publisher publisher;
//Getters and setters are omitted for brevity
//end::naturalid-multiple-attribute-mapping-example[]
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getProductNumber() {
return productNumber;
}
public void setProductNumber(String productNumber) {
this.productNumber = productNumber;
}
public Publisher getPublisher() {
return publisher;
}
public void setPublisher(Publisher publisher) {
this.publisher = publisher;
}
//tag::naturalid-multiple-attribute-mapping-example[]
}
@Entity(name = "Publisher")
public static class Publisher implements Serializable {
@Id
private Long id;
private String name;
//Getters and setters are omitted for brevity
//end::naturalid-multiple-attribute-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::naturalid-multiple-attribute-mapping-example[]
@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}
Publisher publisher = (Publisher) o;
return Objects.equals( id, publisher.id ) &&
Objects.equals( name, publisher.name );
}
@Override
public int hashCode() {
return Objects.hash( id, name );
}
}
//end::naturalid-multiple-attribute-mapping-example[]
}

View File

@ -0,0 +1,120 @@
/*
* 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.Entity;
import javax.persistence.Id;
import org.hibernate.Session;
import org.hibernate.annotations.NaturalId;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
/**
* @author Vlad Mihalcea
*/
public class MutableNaturalIdTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Author.class
};
}
@Test
public void test() {
doInJPA( this::entityManagerFactory, entityManager -> {
Author author = new Author();
author.setId( 1L );
author.setName( "John Doe" );
author.setEmail( "john@acme.com" );
entityManager.persist( author );
} );
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::naturalid-mutable-synchronized-example[]
//tag::naturalid-mutable-example[]
Author author = entityManager
.unwrap(Session.class)
.bySimpleNaturalId( Author.class )
.load( "john@acme.com" );
//end::naturalid-mutable-example[]
author.setEmail( "john.doe@acme.com" );
assertNull(
entityManager
.unwrap(Session.class)
.bySimpleNaturalId( Author.class )
.setSynchronizationEnabled( false )
.load( "john.doe@acme.com" )
);
assertSame( author,
entityManager
.unwrap(Session.class)
.bySimpleNaturalId( Author.class )
.setSynchronizationEnabled( true )
.load( "john.doe@acme.com" )
);
//end::naturalid-mutable-example[]
//end::naturalid-mutable-synchronized-example[]
} );
}
//tag::naturalid-mutable-mapping-example[]
@Entity(name = "Author")
public static class Author {
@Id
private Long id;
private String name;
@NaturalId(mutable = true)
private String email;
//Getters and setters are omitted for brevity
//end::naturalid-mutable-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;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
//tag::naturalid-mutable-mapping-example[]
}
//end::naturalid-mutable-mapping-example[]
}

View File

@ -0,0 +1,118 @@
/*
* 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.Entity;
import javax.persistence.Id;
import org.hibernate.Session;
import org.hibernate.annotations.NaturalId;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertEquals;
/**
* @author Vlad Mihalcea
*/
public class SimpleNaturalIdTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Book.class
};
}
@Test
public void test() {
doInJPA( this::entityManagerFactory, entityManager -> {
Book book = new Book();
book.setId( 1L );
book.setTitle( "High-Performance Java Persistence" );
book.setAuthor( "Vlad Mihalcea" );
book.setIsbn( "978-9730228236" );
entityManager.persist( book );
} );
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::naturalid-simple-load-access-example[]
Book book = entityManager
.unwrap(Session.class)
.bySimpleNaturalId( Book.class )
.load( "978-9730228236" );
//end::naturalid-simple-load-access-example[]
assertEquals("High-Performance Java Persistence", book.getTitle());
} );
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::naturalid-load-access-example[]
Book book = entityManager
.unwrap(Session.class)
.byNaturalId( Book.class )
.using( "isbn", "978-9730228236" )
.load();
//end::naturalid-load-access-example[]
assertEquals("High-Performance Java Persistence", book.getTitle());
} );
}
//tag::naturalid-simple-basic-attribute-mapping-example[]
@Entity(name = "Book")
public static class Book {
@Id
private Long id;
private String title;
private String author;
@NaturalId
private String isbn;
//Getters and setters are omitted for brevity
//end::naturalid-simple-basic-attribute-mapping-example[]
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
//tag::naturalid-simple-basic-attribute-mapping-example[]
}
//end::naturalid-simple-basic-attribute-mapping-example[]
}