java - example - spring data jpa ejemplo
¿Puedo usar Spring Data JPA Auditing sin el archivo orm.xml(utilizando JavaConfig en su lugar)? (3)
Versión corta: no
A partir de JPA 2.0, no es posible definir dicho oyente de entidad sin un archivo XML ( orm.xml
).
JPA 2.0:
Los oyentes de entidades de oyentes de entidades predeterminadas que se aplican a todas las entidades en la unidad de persistencia se pueden especificar por medio del descriptor XML. ( p.93 )
Versión larga: la solución ...
Si todas las entidades de su proyecto amplían una superclase de @EntityListeners({AuditingEntityListener.class})
puede poner @EntityListeners({AuditingEntityListener.class})
en AbstractAuditable
. Los oyentes vinculados a una clase de entidad son heredados por sus subclases.
JPA 2.0:
Múltiples clases de entidad y superclases mapeadas en una jerarquía de herencia pueden definir clases de oyentes y / o métodos de devolución de ciclo de vida directamente en la clase. ( p.93 )
Tenga en cuenta que una subclase puede excluir explícitamente un oyente heredado utilizando la anotación @ExcludeSuperclassListeners
.
Hay una última nota al pie interesante de la especificación que me gustaría citar:
JPA 2.0:
Los oyentes excluidos pueden reintroducirse en una clase de entidad al enlistarlos explícitamente en la anotación EntityListeners o elemento entidad-oyentes XML. ( Nota al pie [45] p.97 )
Aquí hay algunos códigos para ilustrar la solución alternativa:
AbstractAuditableEntity.java
import java.util.Date;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@MappedSuperclass
@EntityListeners({AuditingEntityListener.class}) // AuditingEntityListener will also audit any subclasses of AbstractAuditable...
public abstract class AbstractAuditableEntity {
@Id
@GeneratedValue
private Long id;
@CreatedDate
@Temporal(TemporalType.TIMESTAMP)
private Date createdDate;
@LastModifiedDate
@Temporal(TemporalType.TIMESTAMP)
private Date lastModifiedDate;
}
MyEntity.java
@Entity
public abstract class MyEntity extends AbstractAuditableEntity {
}
Creo que se puede usar una interfaz @EntityListeners
( @EntityListeners
puede aparecer en una interfaz) en lugar de una clase de AbstractAuditable
, pero no lo intenté ...
Referencia: JSR-000317 Java Persistence 2.0 - Versión final
Intento que Spring Data Auditing funcione en mi proyecto Spring 3.2.8 / Spring Data 1.5 / Hibernate 4.
De acuerdo con los documentos de Spring Data Auditing , agregué las anotaciones @CreatedBy
, etc a mis entidades, creadas por la implementación de AuditorAware
, y las formulé desde mi JavaConfig. Sin embargo, nunca parece disparar.
Encuentro los documentos un poco confusos. Parece que la entrada JavaConfig reemplaza la entrada xml, pero no estoy seguro.
Actualmente no tengo ningún archivo orm.xml
en mi aplicación. Para ser completamente honesto, ni siquiera estoy seguro de cómo / cómo configurarlo, o por qué lo necesito. Todas mis entidades están usando anotaciones. He intentado agregar @EntityListeners (AuditingEntityListener.class) a la entidad, pero eso no ha ayudado.
Mi administrador de entidad actual se define sin un archivo persistence.xml:
<!-- entity manager -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter"/>
<property name="packagesToScan" value="com.ia.domain"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.query.substitutions">true ''1'', false ''0''</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
<prop key="hibernate.connection.charSet">UTF-8</prop>
</props>
</property>
</bean>
JavaConfig:
@Configuration
@EnableJpaAuditing
public class AuditConfig {
@Bean
public AuditorAware<User> auditorProvider(){
return new SpringSecurityAuditorAware();
}
}
Entidad:
@EntityListeners({AuditingEntityListener.class})
@Entity
public class User
{
@TableGenerator(name="UUIDGenerator", pkColumnValue="user_id", table="uuid_generator", allocationSize=1)
@Id
@GeneratedValue(strategy=GenerationType.TABLE, generator="UUIDGenerator")
@Column(name="id")
private Long id;
@NotNull
private String username;
@CreatedDate
@NotNull
@Temporal(TemporalType.TIMESTAMP)
@Column(name="created_date", nullable=false)
private Date createdDate;
@LastModifiedDate
@NotNull
@Temporal(TemporalType.TIMESTAMP)
@Column(name="last_modified_date", nullable=false)
private Date lastModifiedDate;
@CreatedBy
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="created_by")
private User createdBy;
@LastModifiedBy
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="last_modified_by")
private User lastModifiedBy;
private String password;
private Boolean enabled;
...
}
He puesto un punto de interrupción en mi clase SpringSecurityAuditorAware
, pero nunca se ve afectado.
¿Todavía necesito un archivo orm.xml? ¿Cómo / dónde se hace referencia a esto desde EntityManager?
En 1.9 de los datos de primavera, puede habilitar las auditorías JPA con un par de anotaciones.
De los documentos - http://docs.spring.io/spring-data/jpa/docs/1.9.4.RELEASE/reference/html/#jpa.auditing
Usar la @EntityListeners(AuditingEntityListener.class)
para habilitar las auditorías clase por clase. Lo uso en una clase base.
También necesitará @EnableJpaAuditing
en una clase @Configuration
para habilitar las auditorías en general.
Usando la respuesta de Stephan, https://.com/a/26240077/715640 ,
Lo hice trabajando usando un oyente personalizado.
@Configurable
public class TimestampedEntityAuditListener {
@PrePersist
public void touchForCreate(AbstractTimestampedEntity target) {
Date now = new Date();
target.setCreated(now);
target.setUpdated(now);
}
@PreUpdate
public void touchForUpdate(AbstractTimestampedEntity target) {
target.setUpdated(new Date());
}
}
Y luego haciendo referencia a ella en mi clase base:
@MappedSuperclass
@EntityListeners({TimestampedEntityAuditListener.class})
public abstract class AbstractTimestampedEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
@Temporal(TemporalType.TIMESTAMP)
private Date created;
@Temporal(TemporalType.TIMESTAMP)
private Date updated;
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getUpdated() {
return updated;
}
public void setUpdated(Date updated) {
this.updated = updated;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
FWIW, estoy usando esto en un proyecto de arranque de primavera, sin un archivo orm.xml.