/*
* 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.pc;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EntityNotFoundException;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Persistence;
import javax.persistence.PersistenceUnitUtil;
import javax.persistence.PersistenceUtil;
import org.hibernate.Hibernate;
import org.hibernate.LockMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.annotations.NaturalId;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.junit.Test;
import org.jboss.logging.Logger;
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.assertTrue;
/**
* @author Vlad Mihalcea
*/
public class PersistenceContextTest extends BaseEntityManagerFunctionalTestCase {
private static final Logger log = Logger.getLogger( PersistenceContextTest.class );
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Person.class,
Book.class,
};
}
@Test
public void test() {
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::pc-unwrap-example[]
Session session = entityManager.unwrap( Session.class );
SessionImplementor sessionImplementor = entityManager.unwrap( SessionImplementor.class );
SessionFactory sessionFactory = entityManager.getEntityManagerFactory().unwrap( SessionFactory.class );
//end::pc-unwrap-example[]
} );
Long _personId = doInJPA( this::entityManagerFactory, entityManager -> {
entityManager.createQuery( "delete from Book" ).executeUpdate();
entityManager.createQuery( "delete from Person" ).executeUpdate();
//tag::pc-persist-jpa-example[]
Person person = new Person();
person.setId( 1L );
person.setName("John Doe");
entityManager.persist( person );
//end::pc-persist-jpa-example[]
//tag::pc-remove-jpa-example[]
entityManager.remove( person );
//end::pc-remove-jpa-example[]
entityManager.persist( person );
Long personId = person.getId();
//tag::pc-get-reference-jpa-example[]
Book book = new Book();
book.setAuthor( entityManager.getReference( Person.class, personId ) );
//end::pc-get-reference-jpa-example[]
return personId;
} );
doInJPA( this::entityManagerFactory, entityManager -> {
Long personId = _personId;
//tag::pc-find-jpa-example[]
Person person = entityManager.find( Person.class, personId );
//end::pc-find-jpa-example[]
} );
doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class );
entityManager.createQuery( "delete from Book" ).executeUpdate();
entityManager.createQuery( "delete from Person" ).executeUpdate();
//tag::pc-persist-native-example[]
Person person = new Person();
person.setId( 1L );
person.setName("John Doe");
session.save( person );
//end::pc-persist-native-example[]
//tag::pc-remove-native-example[]
session.delete( person );
//end::pc-remove-native-example[]
session.save( person );
Long personId = person.getId();
//tag::pc-get-reference-native-example[]
Book book = new Book();
book.setId( 1L );
book.setIsbn( "123-456-7890" );
entityManager.persist( book );
book.setAuthor( session.load( Person.class, personId ) );
//end::pc-get-reference-native-example[]
} );
doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class );
Long personId = _personId;
//tag::pc-find-native-example[]
Person person = session.get( Person.class, personId );
//end::pc-find-native-example[]
} );
doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class );
Long personId = _personId;
//tag::pc-find-by-id-native-example[]
Person person = session.byId( Person.class ).load( personId );
//end::pc-find-by-id-native-example[]
//tag::pc-find-optional-by-id-native-example[]
Optional<Person> optionalPerson = session.byId( Person.class ).loadOptional( personId );
//end::pc-find-optional-by-id-native-example[]
String isbn = "123-456-7890";
//tag::pc-find-by-simple-natural-id-example[]
Book book = session.bySimpleNaturalId( Book.class ).getReference( isbn );
//end::pc-find-by-simple-natural-id-example[]
assertNotNull(book);
} );
doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class );
String isbn = "123-456-7890";
//tag::pc-find-by-natural-id-example[]
Book book = session
.byNaturalId( Book.class )
.using( "isbn", isbn )
.load( );
//end::pc-find-by-natural-id-example[]
assertNotNull(book);
//tag::pc-find-optional-by-simple-natural-id-example[]
Optional<Book> optionalBook = session
.byNaturalId( Book.class )
.using( "isbn", isbn )
.loadOptional( );
//end::pc-find-optional-by-simple-natural-id-example[]
} );
doInJPA( this::entityManagerFactory, entityManager -> {
Long personId = _personId;
//tag::pc-managed-state-jpa-example[]
Person person = entityManager.find( Person.class, personId );
person.setName("John Doe");
entityManager.flush();
//end::pc-managed-state-jpa-example[]
} );
doInJPA( this::entityManagerFactory, entityManager -> {
Long personId = _personId;
//tag::pc-refresh-jpa-example[]
Person person = entityManager.find( Person.class, personId );
entityManager.createQuery( "update Person set name = UPPER(name)" ).executeUpdate();
entityManager.refresh( person );
assertEquals("JOHN DOE", person.getName() );
//end::pc-refresh-jpa-example[]
} );
try {
doInJPA( this::entityManagerFactory, entityManager -> {
Long personId = _personId;
//tag::pc-refresh-child-entity-jpa-example[]
try {
Person person = entityManager.find( Person.class, personId );
Book book = new Book();
book.setId( 100L );
book.setTitle( "Hibernate User Guide" );
book.setAuthor( person );
person.getBooks().add( book );
entityManager.refresh( person );
}
catch ( EntityNotFoundException expected ) {
log.info( "Beware when cascading the refresh associations to transient entities!" );
}
//end::pc-refresh-child-entity-jpa-example[]
} );
}
catch ( Exception expected ) {
}
doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class );
Long personId = _personId;
//tag::pc-managed-state-native-example[]
Person person = session.byId( Person.class ).load( personId );
person.setName("John Doe");
entityManager.flush();
//end::pc-managed-state-native-example[]
} );
doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class );
Long personId = _personId;
//tag::pc-refresh-native-example[]
Person person = session.byId( Person.class ).load( personId );
session.doWork( connection -> {
try(Statement statement = connection.createStatement()) {
statement.executeUpdate( "UPDATE Person SET name = UPPER(name)" );
}
} );
session.refresh( person );
assertEquals("JOHN DOE", person.getName() );
//end::pc-refresh-native-example[]
} );
doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class );
Long personId = _personId;
//tag::pc-detach-reattach-lock-example[]
Person person = session.byId( Person.class ).load( personId );
//Clear the Session so the person entity becomes detached
session.clear();
person.setName( "Mr. John Doe" );
session.lock( person, LockMode.NONE );
//end::pc-detach-reattach-lock-example[]
} );
doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class );
Long personId = _personId;
//tag::pc-detach-reattach-saveOrUpdate-example[]
Person person = session.byId( Person.class ).load( personId );
//Clear the Session so the person entity becomes detached
session.clear();
person.setName( "Mr. John Doe" );
session.saveOrUpdate( person );
//end::pc-detach-reattach-saveOrUpdate-example[]
} );
doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class );
Long personId = _personId;
Person personDetachedReference = session.byId( Person.class ).load( personId );
//Clear the Session so the person entity becomes detached
session.clear();
new MergeVisualizer( session ).merge( personDetachedReference );
} );
doInJPA( this::entityManagerFactory, entityManager -> {
Long personId = _personId;
//tag::pc-merge-jpa-example[]
Person person = entityManager.find( Person.class, personId );
//Clear the EntityManager so the person entity becomes detached
entityManager.clear();
person.setName( "Mr. John Doe" );
person = entityManager.merge( person );
//end::pc-merge-jpa-example[]
//tag::pc-contains-jpa-example[]
boolean contained = entityManager.contains( person );
//end::pc-contains-jpa-example[]
assertTrue( contained );
//tag::pc-verify-lazy-jpa-example[]
PersistenceUnitUtil persistenceUnitUtil = entityManager.getEntityManagerFactory().getPersistenceUnitUtil();
boolean personInitialized = persistenceUnitUtil.isLoaded( person );
boolean personBooksInitialized = persistenceUnitUtil.isLoaded( person.getBooks() );
boolean personNameInitialized = persistenceUnitUtil.isLoaded( person, "name" );
//end::pc-verify-lazy-jpa-example[]
} );
doInJPA( this::entityManagerFactory, entityManager -> {
Long personId = _personId;
Person person = entityManager.find( Person.class, personId );
//tag::pc-verify-lazy-jpa-alternative-example[]
PersistenceUtil persistenceUnitUtil = Persistence.getPersistenceUtil();
boolean personInitialized = persistenceUnitUtil.isLoaded( person );
boolean personBooksInitialized = persistenceUnitUtil.isLoaded( person.getBooks() );
boolean personNameInitialized = persistenceUnitUtil.isLoaded( person, "name" );
//end::pc-verify-lazy-jpa-alternative-example[]
} );
doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class );
Long personId = _personId;
//tag::pc-merge-native-example[]
Person person = session.byId( Person.class ).load( personId );
//Clear the Session so the person entity becomes detached
session.clear();
person.setName( "Mr. John Doe" );
person = (Person) session.merge( person );
//end::pc-merge-native-example[]
//tag::pc-contains-native-example[]
boolean contained = session.contains( person );
//end::pc-contains-native-example[]
assertTrue( contained );
//tag::pc-verify-lazy-native-example[]
boolean personInitialized = Hibernate.isInitialized( person );
boolean personBooksInitialized = Hibernate.isInitialized( person.getBooks() );
boolean personNameInitialized = Hibernate.isPropertyInitialized( person, "name" );
//end::pc-verify-lazy-native-example[]
} );
}
public static class MergeVisualizer {
private final Session session;
public MergeVisualizer(Session session) {
this.session = session;
}
//tag::pc-merge-visualize-example[]
public Person merge(Person detached) {
Person newReference = session.byId( Person.class ).load( detached.getId() );
newReference.setName( detached.getName() );
return newReference;
}
//end::pc-merge-visualize-example[]
}
@Entity(name = "Person")
public static class Person {
@Id
private Long id;
private String name;
@OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
private List<Book> books = new ArrayList<>( );
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 List<Book> getBooks() {
return books;
}
}
//tag::pc-find-by-natural-id-entity-example[]
@Entity(name = "Book")
public static class Book {
@Id
private Long id;
private String title;
@NaturalId
private String isbn;
@ManyToOne
private Person author;
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 Person getAuthor() {
return author;
}
public void setAuthor(Person author) {
this.author = author;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
}
//end::pc-find-by-natural-id-entity-example[]
}