HHH-11186 - Add example for all Hibernate annotations
Document more annotations: - @NotFound
This commit is contained in:
parent
e77d18c0d1
commit
7b78ee9981
|
@ -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`
|
||||||
|
|
||||||
|
|
|
@ -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]
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
|
@ -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[]
|
||||||
|
}
|
Loading…
Reference in New Issue