我们需要使用envers审核现有表。我们没有hibernate.xml,而不是使用application-context.xml。我们正在通过" liquibase-changeset"创建模式,然后如何通过@Entity和@Audited等注释创建。
如何解决此问题?
我添加了hibernate配置
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
<prop key="hibernate.ejb.event.post-insert">org.hibernate.ejb.event.EJB3PostInsertEventListener,org.hibernate.envers.event.AuditEventListener</prop>
<prop key="hibernate.ejb.event.post-update">org.hibernate.ejb.event.EJB3PostUpdateEventListener,org.hibernate.envers.event.AuditEventListener</prop>
<prop key="hibernate.ejb.event.post-delete">org.hibernate.ejb.event.EJB3PostDeleteEventListener,org.hibernate.envers.event.AuditEventListener</prop>
<prop key="hibernate.ejb.event.pre-collection-update">org.hibernate.envers.event.AuditEventListener</prop>
<!-- <prop key="hibernate.ejb.event.pre-collection-remove">org.hibernate.envers.event.AuditEventListener</prop>
<prop key="hibernate.ejb.event.post-collection-recreate">org.hibernate.envers.event.AuditEventListener</prop> -->
<prop key="org.hibernate.envers.revision_field_name">REV</prop>
<prop key="org.hibernate.envers.revision_type_field_name">REVTYPE</prop>
<prop key="org.hibernate.envers.auditTablePrefix"></prop>
<prop key="org.hibernate.envers.auditTableSuffix">_HISTORY</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
在我的域类
中添加了@Audited注释@Entity
@Audited
@Table(name="user")
public class User implements Serializable {
但是这个配置删除了我现有的表
e.g
Mydatabase
-----------
user
product
order_details
user_role
login
我的数据库中有5个表。运行我的应用程序后,它显示3个表。而不是创建&#34;审计&#34;表,它删除现有表。
Mydatabase
-----------
user
product
order_details
如何在不触及现有表的情况下创建审计(_HISTORY)表???
答案 0 :(得分:3)
在Liquibase变更集中,定义审计表定义,就像对任何其他表一样。
在spring-hibernate ocnfiguration中跳过hibernate.hbm2ddl.auto
属性。这将指示hibernate不对架构做任何事情。
保持其余的配置,这应该有效。
只需确保架构和配置中的审计表名称匹配。
链接到文档,详细说明如何使用ant
在案例架构中完成generated答案 1 :(得分:3)
我遇到了同样的问题,要解决它,我按照接下来的步骤进行操作:
更改:
<prop key="hibernate.hbm2ddl.auto">create</prop>
为:
<prop key="hibernate.hbm2ddl.auto">update</prop>
如果您使用ENVERS Hibernet-envers 3.5.5或+,您应该在应用程序环境中使用此配置:
<property name="eventListeners">
<map>
<entry key="post-insert" >
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-update">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-delete">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="pre-collection-update">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="pre-collection-remove">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
<entry key="post-collection-recreate">
<bean class="org.hibernate.envers.event.AuditEventListener" />
</entry>
</map>
</property>
您必须定义一个像这样的修订实体:
@Entity
@Table(name = "MY_REVINFO")
@RevisionEntity(MyRevisionListener.class)//@see next class
public class MyRevisionEntity {
private static final long serialVersionUID =1L;
@Id
@GeneratedValue
@RevisionNumber
private int id;
@RevisionTimestamp
private long timestamp;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Transient
public Date getRevisionDate() {
return new Date(timestamp);
}
@Column(name = "USER_NAME")
private String userName;
@Column(name = "DATE_OPER")
private Date dateOperation;
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof DefaultRevisionEntity)) return false;
DefaultRevisionEntity that = (DefaultRevisionEntity) o;
if (id != that.getId()) return false;
if (timestamp != that.getTimestamp()) return false;
return true;
}
public int hashCode() {
int result;
result = id;
result = 31 * result + (int) (timestamp ^ (timestamp >>> 32));
return result;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Date getDateOperation() {
return dateOperation;
}
public void setDateOperation(Date dateOperation) {
this.dateOperation = dateOperation;
}
public String toString() {
return "DefaultRevisionEntity(id = " + id + ", revisionDate = " + DateFormat.getDateTimeInstance().format(getRevisionDate()) + ")";
}
}
在application-context.xml中添加此新实体的映射为:
<value>mypackage.MyRevisionEntity</value>
创建监听器(如果您想保存用户名和操作时间,这非常有帮助):
public class MyRevisionListener implements RevisionListener {
public void newRevision(Object revisionEntity) {
MyRevisionEntity revision = (MyRevisionEntity) revisionEntity;
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
String userName="---";
if (userDetails != null) {
userName=userDetails.getUsername();
} else {
userName="UNKNOWN";
}
revision.setUserName(userName);
revision.setDateOperation(new Date(revision.getTimestamp()));
}
}
清理,安装和运行您的应用程序。
如果问题仍然存在,请尝试升级您的Envers版本(Hibrenate-envers和Hibernate-core)
希望得到这个帮助。
答案 2 :(得分:1)
尝试更改DDL策略:
<prop key="hibernate.hbm2ddl.auto">create</prop>
为:
<prop key="hibernate.hbm2ddl.auto">update</prop>
更新 DDL生成策略不应删除任何现有表。
答案 3 :(得分:0)
我正在使用带有Hibernate实现的JPA开发一个项目,并且我们设法使用基于Spring上下文xml的配置使envers工作没有太多问题(我们都不使用persistence.xml)。
我们的配置基于Spring JPA支持,但您可以找到类似的解决方案:
<bean id="projectEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
</bean>
</property>
<property name="packagesToScan">
<list>
<value>com.teimas.myproject.bo</value>
<value>com.teimas.myproject.bo.commons</value>
<value>com.teimas.myproject.bo.util</value>
</list>
</property>
<property name="persistenceUnitName" value="projectPU" />
<property name="jtaDataSource" ref="projectDataSourceTarget" />
<!-- Other ptops for hibernate config -->
<property name="jpaProperties" ref="jpaHibernateProperties" />
</bean>
<util:properties id="jpaHibernateProperties">
<prop key="hibernate.transaction.jta.platform">
org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform
</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<!-- validate | update | create | create-drop -->
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="javax.persistence.transactionType">JTA</prop>
<prop key="javax.persistence.validation.mode">AUTO</prop>
</util:properties>
关键是我们使用hibernate对象作为JPA提供者:org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter,我们添加packagesToScan属性来告诉hibernate扫描这些包中的注释。所以Hibernate找到Envers和Validation anotations,一切正常。
希望这有帮助。