HHH-11186 - Add example for all Hibernate annotations

Document more annotations:

- @NotFound
This commit is contained in:
Fábio Ueno 2017-02-20 17:46:59 -03:00 committed by Vlad Mihalcea
parent e77d18c0d1
commit 7b78ee9981
3 changed files with 230 additions and 0 deletions

View File

@ -1006,6 +1006,8 @@ The `NotFoundAction` defines with two possibilities:
`EXCEPTION`:: An exception is thrown when an element is not found (default and recommended). `EXCEPTION`:: An exception is thrown when an element is not found (default and recommended).
`IGNORE`:: Ignore the element when not found in the database. `IGNORE`:: Ignore the element when not found in the database.
See the <<chapters/domain/associations.adoc#associations-not-found,`@NotFound` mapping>> section for more info.
[[annotations-hibernate-ondelete]] [[annotations-hibernate-ondelete]]
==== `@OnDelete` ==== `@OnDelete`

View File

@ -388,3 +388,69 @@ include::{extrasdir}/associations-many-to-many-bidirectional-with-link-entity-li
==== ====
There is only one delete statement executed because, this time, the association is controlled by the `@ManyToOne` side which only has to monitor the state of the underlying foreign key relationship to trigger the right DML statement. There is only one delete statement executed because, this time, the association is controlled by the `@ManyToOne` side which only has to monitor the state of the underlying foreign key relationship to trigger the right DML statement.
[[associations-not-found]]
==== `@NotFound` association mapping
When dealing with associations which are not enforced by a Foreign Key,
it's possible to bump into inconsistencies if the child record cannot reference a parent entity.
By default, Hibernate will complain whenever a child association references a non-existing parent record.
However, you can configure this behavior so that Hibernate can ignore such an Exception and simply assign `null` as a parent object referenced.
To ignore non-existing parent entity references, even though not really recommended, it's possible to use the annotation `org.hibernate.annotation.NotFound` annotation with a value of `org.hibernate.annotations.NotFoundAction.IGNORE`.
Considering the following `City` and `Person` entity mappings:
[[associations-not-found-domain-model-example]]
.`@NotFound` mapping example
====
[source,java]
----
include::{sourcedir}/NotFoundTest.java[tags=associations-not-found-domain-model-example,indent=0]
----
====
If we have the following entities in our database:
[[associations-not-found-persist-example]]
.`@NotFound` mapping example
====
[source,java]
----
include::{sourcedir}/NotFoundTest.java[tags=associations-not-found-persist-example,indent=0]
----
====
When loading the `Person` entity, Hibernate is able to locate the associated `City` parent entity:
[[associations-not-found-find-example]]
.`@NotFound` find existing entity example
====
[source,java]
----
include::{sourcedir}/NotFoundTest.java[tags=associations-not-found-find-example,indent=0]
----
====
However, if we change the `cityName` attribute to a non-existing city:
[[associations-not-found-non-existing-persist-example]]
.`@NotFound` change to non-existing City example
====
[source,java]
----
include::{sourcedir}/NotFoundTest.java[tags=associations-not-found-non-existing-persist-example,indent=0]
----
====
Hibernate is not going to throw any exception, and it will assign a value of `null` for the non-existing `City` entity reference:
[[associations-not-found-non-existing-find-example]]
.`@NotFound` find non-existing City example
====
[source,java]
----
include::{sourcedir}/NotFoundTest.java[tags=associations-not-found-non-existing-find-example,indent=0]
----
====

View File

@ -0,0 +1,162 @@
package org.hibernate.userguide.associations;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
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.assertNull;
/**
* @author Fábio Ueno
*/
public class NotFoundTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Person.class,
City.class
};
}
@Test
public void test() {
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::associations-not-found-persist-example[]
City _NewYork = new City();
_NewYork.setName( "New York" );
entityManager.persist( _NewYork );
Person person = new Person();
person.setId( 1L );
person.setName( "John Doe" );
person.setCityName( "New York" );
entityManager.persist( person );
//end::associations-not-found-persist-example[]
} );
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::associations-not-found-find-example[]
Person person = entityManager.find( Person.class, 1L );
assertEquals( "New York", person.getCity().getName() );
//end::associations-not-found-find-example[]
//tag::associations-not-found-non-existing-persist-example[]
person.setCityName( "Atlantis" );
//end::associations-not-found-non-existing-persist-example[]
} );
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::associations-not-found-non-existing-find-example[]
Person person = entityManager.find( Person.class, 1L );
assertEquals( "Atlantis", person.getCityName() );
assertNull( null, person.getCity() );
//end::associations-not-found-non-existing-find-example[]
} );
}
//tag::associations-not-found-domain-model-example[]
@Entity
@Table( name = "Person" )
public static class Person {
@Id
private Long id;
private String name;
private String cityName;
@ManyToOne( fetch = FetchType.LAZY )
@NotFound ( action = NotFoundAction.IGNORE )
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
insertable = false,
updatable = false
)
private City city;
//Getters and setters are omitted for brevity
//end::associations-not-found-domain-model-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 getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
this.city = null;
}
public City getCity() {
return city;
}
//tag::associations-not-found-domain-model-example[]
}
@Entity
@Table( name = "City" )
public static class City implements Serializable {
@Id
@GeneratedValue
private Long id;
private String name;
//Getters and setters are omitted for brevity
//end::associations-not-found-domain-model-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::associations-not-found-domain-model-example[]
}
//end::associations-not-found-domain-model-example[]
}