Skip to content

Commit

Permalink
HHH-2643 - Improve Session.refresh() Javdoc to clarify contract
Browse files Browse the repository at this point in the history
Instead of writing it in the JavaDocs, it's much more appropriate to document this behavior in the User Guide

(cherry picked from commit 5629457)

Conflicts:
	documentation/src/main/asciidoc/userguide/chapters/pc/PersistenceContext.adoc
	documentation/src/test/java/org/hibernate/userguide/pc/PersistenceContextTest.java
  • Loading branch information
vladmihalcea authored and gbadner committed Feb 15, 2017
1 parent 517877f commit 7541a2d
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 2 deletions.
Expand Up @@ -262,6 +262,29 @@ However, please note that Hibernate has the capability to handle this automatica
See the discussion of non-identifier <<chapters/domain/basic_types.adoc#mapping-generated,generated attributes>>.
====

[[pc-refresh-gotchas]]
==== Refresh gotchas

The `refresh` entity state transition is meant to overwrite the entity attributes according to the info currently contained in the associated database record.

However, you have to be very careful when cascading the refresh action to any transient entity.

For instance, consider the following example:

[[pc-refresh-child-entity-jpa-example]]
.Refreshing entity state gotcha
====
[source, JAVA, indent=0]
----
include::{sourcedir}/PersistenceContextTest.java[tags=pc-refresh-child-entity-jpa-example]
----
====

In the aforementioned example, an `EntityNotFoundException` is thrown because the `Book` entity is still in a transient state.
When the refresh action is cascaded from the `Person` entity, Hibernate will not be able to locate the `Book` entity in the database.

For this reason, you should be very careful when mixing the refresh action with transient child entity objects.

[[pc-detach]]
=== Working with detached data

Expand Down Expand Up @@ -442,4 +465,4 @@ To verify if an entity instance is currently attached to the running persistence
----
include::{sourcedir-caching}/FirstLevelCacheTest.java[tags=caching-management-contains-example]
----
====
====
Expand Up @@ -9,7 +9,9 @@
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EntityNotFoundException;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
Expand All @@ -28,6 +30,8 @@
import org.junit.Test;

import static org.hibernate.userguide.util.TransactionUtil.doInJPA;
import org.jboss.logging.Logger;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
Expand All @@ -37,6 +41,8 @@
*/
public class PersistenceContextTest extends BaseEntityManagerFunctionalTestCase {

private static final Logger log = Logger.getLogger( PersistenceContextTest.class );

@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Expand Down Expand Up @@ -172,6 +178,31 @@ public void test() {
//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;
Expand Down Expand Up @@ -335,7 +366,7 @@ public static class Person {

private String name;

@OneToMany(mappedBy = "author")
@OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
private List<Book> books = new ArrayList<>( );

public Long getId() {
Expand Down

0 comments on commit 7541a2d

Please sign in to comment.