HHH-15715 - Fix broken links in docs
Signed-off-by: Jan Schatteman <jschatte@redhat.com>
This commit is contained in:
parent
0d295e9f11
commit
07274cd2ce
|
@ -929,14 +929,6 @@ include::{docTestsDir}/MapKeyTypeTest.java[tags=collections-map-custom-key-type-
|
||||||
----
|
----
|
||||||
====
|
====
|
||||||
|
|
||||||
The associated `TimestampEpochType` looks as follows:
|
|
||||||
|
|
||||||
----
|
|
||||||
include::{docTestsDir}/type/TimestampEpochType.java[tags=collections-map-custom-key-type-mapping-example,indent=0]
|
|
||||||
----
|
|
||||||
|
|
||||||
The `TimestampEpochType` allows us to map a Unix timestamp since epoch to a `java.util.Date`.
|
|
||||||
But, without the `@MapKeyType` Hibernate annotation, it would not be possible to customize the `Map` key type.
|
|
||||||
|
|
||||||
[[collections-map-key-class]]
|
[[collections-map-key-class]]
|
||||||
===== Maps having an interface type as the key
|
===== Maps having an interface type as the key
|
||||||
|
|
|
@ -81,7 +81,12 @@ Here is an example of a custom load event listener:
|
||||||
====
|
====
|
||||||
[source, JAVA, indent=0]
|
[source, JAVA, indent=0]
|
||||||
----
|
----
|
||||||
include::{sourcedir}/ListenerTest.java[tags=events-interceptors-load-listener-example]
|
include::{sourcedir}/ListenerTest.java[tags=events-interceptors-load-listener-example-part1]
|
||||||
|
----
|
||||||
|
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
include::{sourcedir}/ListenerTest.java[tags=events-interceptors-load-listener-example-part2]
|
||||||
----
|
----
|
||||||
====
|
====
|
||||||
|
|
||||||
|
|
|
@ -140,8 +140,10 @@ public class MapKeyTypeTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
joinColumns = @JoinColumn(name = "person_id")
|
joinColumns = @JoinColumn(name = "person_id")
|
||||||
)
|
)
|
||||||
@MapKeyJdbcTypeCode(Types.BIGINT)
|
@MapKeyJdbcTypeCode(Types.BIGINT)
|
||||||
|
//end::collections-map-custom-key-type-mapping-example[]
|
||||||
// todo (6.0) : figure out why `@MapKeyTemporal` did not work. imo it should
|
// todo (6.0) : figure out why `@MapKeyTemporal` did not work. imo it should
|
||||||
// @MapKeyTemporal(TemporalType.TIMESTAMP)
|
// @MapKeyTemporal(TemporalType.TIMESTAMP)
|
||||||
|
//tag::collections-map-custom-key-type-mapping-example[]
|
||||||
@MapKeyJavaType(JdbcTimestampJavaType.class)
|
@MapKeyJavaType(JdbcTimestampJavaType.class)
|
||||||
@MapKeyColumn(name = "call_timestamp_epoch")
|
@MapKeyColumn(name = "call_timestamp_epoch")
|
||||||
@Column(name = "phone_number")
|
@Column(name = "phone_number")
|
||||||
|
|
|
@ -0,0 +1,179 @@
|
||||||
|
/*
|
||||||
|
* 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.events;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.Date;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.EntityListeners;
|
||||||
|
import jakarta.persistence.EntityManagerFactory;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.PostLoad;
|
||||||
|
import jakarta.persistence.PrePersist;
|
||||||
|
import jakarta.persistence.PreUpdate;
|
||||||
|
import jakarta.persistence.Transient;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.event.service.spi.EventListenerRegistry;
|
||||||
|
import org.hibernate.event.spi.EventType;
|
||||||
|
import org.hibernate.event.spi.LoadEvent;
|
||||||
|
import org.hibernate.event.spi.LoadEventListener;
|
||||||
|
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlad Mihalcea
|
||||||
|
*/
|
||||||
|
public class ListenerTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class<?>[] {
|
||||||
|
Person.class,
|
||||||
|
Customer.class
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SecurityException.class)
|
||||||
|
public void testLoadListener() {
|
||||||
|
Serializable customerId = 1L;
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::events-interceptors-load-listener-example-part1[]
|
||||||
|
EntityManagerFactory entityManagerFactory = entityManagerFactory();
|
||||||
|
SessionFactoryImplementor sessionFactory = entityManagerFactory.unwrap( SessionFactoryImplementor.class );
|
||||||
|
sessionFactory
|
||||||
|
.getServiceRegistry()
|
||||||
|
.getService( EventListenerRegistry.class )
|
||||||
|
.prependListeners( EventType.LOAD, new SecuredLoadEntityListener() );
|
||||||
|
|
||||||
|
Customer customer = entityManager.find( Customer.class, customerId );
|
||||||
|
//end::events-interceptors-load-listener-example-part1[]
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJPACallback() {
|
||||||
|
Long personId = 1L;
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Person person = new Person();
|
||||||
|
person.id = personId;
|
||||||
|
person.name = "John Doe";
|
||||||
|
person.dateOfBirth = Timestamp.valueOf(LocalDateTime.of( 2000, 1, 1, 0, 0, 0 ));
|
||||||
|
entityManager.persist( person );
|
||||||
|
} );
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Person person = entityManager.find( Person.class, personId );
|
||||||
|
assertTrue(person.age > 0);
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "Customer")
|
||||||
|
public static class Customer {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Customer() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Customer(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//tag::events-jpa-callbacks-example[]
|
||||||
|
@Entity(name = "Person")
|
||||||
|
@EntityListeners( LastUpdateListener.class )
|
||||||
|
public static class Person {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private Date dateOfBirth;
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private long age;
|
||||||
|
|
||||||
|
private Date lastUpdate;
|
||||||
|
|
||||||
|
public void setLastUpdate(Date lastUpdate) {
|
||||||
|
this.lastUpdate = lastUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the transient property at load time based on a calculation.
|
||||||
|
* Note that a native Hibernate formula mapping is better for this purpose.
|
||||||
|
*/
|
||||||
|
@PostLoad
|
||||||
|
public void calculateAge() {
|
||||||
|
age = ChronoUnit.YEARS.between( LocalDateTime.ofInstant(
|
||||||
|
Instant.ofEpochMilli( dateOfBirth.getTime()), ZoneOffset.UTC),
|
||||||
|
LocalDateTime.now()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class LastUpdateListener {
|
||||||
|
|
||||||
|
@PreUpdate
|
||||||
|
@PrePersist
|
||||||
|
public void setLastUpdate( Person p ) {
|
||||||
|
p.setLastUpdate( new Date() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//end::events-jpa-callbacks-example[]
|
||||||
|
|
||||||
|
//tag::events-interceptors-load-listener-example-part2[]
|
||||||
|
public static class SecuredLoadEntityListener implements LoadEventListener {
|
||||||
|
// this is the single method defined by the LoadEventListener interface
|
||||||
|
public void onLoad(LoadEvent event, LoadType loadType)
|
||||||
|
throws HibernateException {
|
||||||
|
if ( !Principal.isAuthorized( event.getEntityClassName(), event.getEntityId() ) ) {
|
||||||
|
throw new SecurityException( "Unauthorized access" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//end::events-interceptors-load-listener-example-part2[]
|
||||||
|
|
||||||
|
public static class Principal {
|
||||||
|
public static boolean isAuthorized(String clazz, Object id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,9 +9,8 @@ package org.hibernate.userguide.spatial;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
|
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
import org.hibernate.dialect.PostgreSQLDialect;
|
||||||
import org.hibernate.spatial.dialect.postgis.PostgisDialect;
|
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
|
||||||
import org.hibernate.spatial.dialect.postgis.PostgisPG95Dialect;
|
|
||||||
|
|
||||||
import org.hibernate.testing.RequiresDialect;
|
import org.hibernate.testing.RequiresDialect;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -31,10 +30,10 @@ import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
*/
|
*/
|
||||||
@RequiresDialect(PostgisPG95Dialect.class)
|
@RequiresDialect(PostgreSQLDialect.class)
|
||||||
public class SpatialTest extends BaseEntityManagerFunctionalTestCase {
|
public class SpatialTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
private GeometryFactory geometryFactory = new GeometryFactory();
|
private final GeometryFactory geometryFactory = new GeometryFactory();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<?>[] getAnnotatedClasses() {
|
protected Class<?>[] getAnnotatedClasses() {
|
Loading…
Reference in New Issue