2017-08-21 66 views
0

我試圖讓Javer與我的項目安裝。我使用Hibernate JPA,我相信我已經正確配置了一切。Javers「jv_commit」不存在

這裏是我的Spring配置:

<bean id="auditDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 
    <property name="driverClassName" value="${jdbc.driverClassName}"/> 
    <property name="url" value="${jdbc.audit.url}"/> 
    <property name="username" value="${jdbc.audit.username}"/> 
    <property name="password" value="${jdbc.audit.password}"/> 
    <property name="maxActive" value="100"/> 
    <property name="maxWait" value="1000"/> 
    <property name="poolPreparedStatements" value="true"/> 
    <property name="defaultAutoCommit" value="true"/> 
    <property name="validationQuery" value="${jdbc.validationQuery}"/> 
    <property name="testOnBorrow" value="true"/> 
</bean> 

<bean id="auditSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" destroy-method="destroy"> 
    <property name="dataSource" ref="auditDataSource"/> 
    <property name="configLocation" value="classpath:hibernate.audit.cfg.xml"/> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">${hibernate.dialect}</prop> 
      <prop key="hibernate.query.substitutions">true 'Y', false 'N'</prop> 
      <prop key="hibernate.cache.use_second_level_cache">true</prop> 
      <prop key="hibernate.show_sql">false</prop> 
      <prop key="hibernate.format_sql">false</prop> 
      <prop key="hibernate.use_sql_comments">false</prop> 
      <!--<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>--> 
      <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop> 
      <!-- Hibernate Search index directory --> 
      <prop key="hibernate.search.default.indexBase">${app.search.index.basedir}</prop> 
     </props> 
     <!-- Turn batching off for better error messages under PostgreSQL --> 
     <!-- hibernate.jdbc.batch_size=0 --> 
    </property> 
</bean> 

<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) --> 
<bean id="auditTransactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="auditSessionFactory"/> 
</bean> 

<bean id="javersRepoConnectionProvider" class="com.dsc.discus.ng.audit.javers.JaversRepoConnectionProvider"> 
    <constructor-arg name="dataSource" ref="auditDataSource"/> 
</bean> 

<bean id="auditController" class="com.dsc.discus.ng.audit.javers.JaversAuditController"> 
    <constructor-arg name="javersRepoConnectionProvider" ref="javersRepoConnectionProvider"/> 
    <constructor-arg name="transactionManager" ref="auditTransactionManager"/> 
</bean> 

的JaversAuditController豆:

public class JaversAuditController extends AuditController { 
private final JaversSqlRepository javersSqlRepository; 
private final Javers javers; 

public JaversAuditController(JaversRepoConnectionProvider javersRepoConnectionProvider, PlatformTransactionManager transactionManager) { 
    javersSqlRepository = SqlRepositoryBuilder.sqlRepository() 
      .withConnectionProvider(javersRepoConnectionProvider) 
      .withDialect(DialectName.MYSQL) 
      .build(); 

    javers = TransactionalJaversBuilder.javers() 
      .withTxManager(transactionManager) 
      .withObjectAccessHook(new HibernateUnproxyObjectAccessHook()) 
      .withMappingStyle(MappingStyle.BEAN) 
      .registerJaversRepository(javersSqlRepository) 
      .build(); 
} 

@Override 
public void addModified(BaseEntity entity) { 
    addModified(entity, null); 
} 

@Override 
public void addModified(BaseEntity entity, Map<String, String> extraParams) { 
    if (javers != null && entity != null) { 
     if (extraParams != null) { 
      javers.commit(entity.getModifiedBy(), entity, extraParams); 
     } 
     else { 
      javers.commit(entity.getModifiedBy(), entity); 
     } 
    } 
} 

public JaversSqlRepository getJaversSqlRepository() { 
    return javersSqlRepository; 
} 

public Javers getJavers() { 
    return javers; 
} 

我不得不使用BEAN的映射風格,因爲JPA註釋是對實體的存取。

這裏是JaversRepoConnectionProvider豆:

public class JaversRepoConnectionProvider implements ConnectionProvider { 
private DataSource dataSource; 

public JaversRepoConnectionProvider(DataSource dataSource) { 
    this.dataSource = dataSource; 
} 

@Override 
public Connection getConnection() throws SQLException { 
    return dataSource.getConnection(); 
} 

}

我做了人工審覈。也就是說,每次保存一個實體時,我都會調用javers.commit()方法。碰巧,我試圖保存的第一件事情導致MySQL語法錯誤,指出表「jv_commit」不存在。該文檔指出必要的表格會自動創建,所以我必須缺少一些東西。請提前告知和感謝。

截斷堆棧跟蹤:。

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'discus_eng_audit.jv_commit' doesn't exist 
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) 
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) 
at com.mysql.jdbc.Util.getInstance(Util.java:386) 
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1054) 
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4237) 
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4169) 
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2617) 
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2778) 
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2825) 
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2156) 
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2323) 
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96) 
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96) 
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96) 
at org.polyjdbc.core.transaction.Transaction.executeQuery(Transaction.java:59) 
at org.polyjdbc.core.query.TransactionalQueryRunner.queryCollection(TransactionalQueryRunner.java:86) 
at org.polyjdbc.core.query.TransactionalQueryRunner.queryList(TransactionalQueryRunner.java:76) 
at org.javers.repository.sql.PolyUtil.queryForBigDecimalList(PolyUtil.java:27) 
at org.javers.repository.sql.PolyUtil.queryForOptionalBigDecimal(PolyUtil.java:36) 
at org.javers.repository.sql.repositories.CommitMetadataRepository.selectMaxCommitId(CommitMetadataRepository.java:86) 
at org.javers.repository.sql.repositories.CommitMetadataRepository.getCommitHeadId(CommitMetadataRepository.java:75) 
at org.javers.repository.sql.JaversSqlRepository.getHeadId(JaversSqlRepository.java:76) 
at org.javers.repository.api.JaversExtendedRepository.getHeadId(JaversExtendedRepository.java:137) 
at org.javers.core.commit.CommitIdFactory.nextId(CommitIdFactory.java:26) 
at org.javers.core.commit.CommitFactory.newCommitMetadata(CommitFactory.java:79) 
at org.javers.core.commit.CommitFactory.create(CommitFactory.java:69) 
at org.javers.core.JaversCore.commit(JaversCore.java:82) 
at org.javers.core.JaversCore.commit(JaversCore.java:67) 
at org.javers.spring.jpa.JaversTransactionalDecorator.commit(JaversTransactionalDecorator.java:58) 
at com.dsc.discus.ng.audit.javers.JaversAuditController.addModified(JaversAuditController.java:56) 
at com.dsc.discus.ng.audit.javers.JaversAuditController.addModified(JaversAuditController.java:46) 
at com.dsc.discus.ng.model.persistence.dao.hibernate.BaseDaoHibernate.save(BaseDaoHibernate.java:146) 
at com.dsc.discus.ng.model.persistence.dao.hibernate.BaseDaoHibernate.save(BaseDaoHibernate.java:26) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 
+1

JaVers在啓動時創建它的表,很難猜測爲什麼表沒有在您的情況下創建表。這可能是由數據庫錯誤引起的。你的javers日誌裏有什麼? –

+0

這讓我指出了正確的方向。謝謝。 TransactionalJaversBuilder.build()方法不確保創建表。 – MiseryMachine

回答

-1

事實證明,所述TransactionalJaversBuilder.javers()建立()方法不保證這些表被創建,像標準JaversBuilder.javers()建立()方法。我不確定這是否是TransactionalJaversBuilder中的錯誤。我的解決方法是Javers對象建立後致電ensureSchema():

public JaversAuditController(JaversRepoConnectionProvider javersRepoConnectionProvider, PlatformTransactionManager transactionManager) { 
    javersSqlRepository = SqlRepositoryBuilder.sqlRepository() 
      .withConnectionProvider(javersRepoConnectionProvider) 
      .withDialect(DialectName.MYSQL) 
      .build(); 


    javers = TransactionalJaversBuilder.javers() 
      .withTxManager(transactionManager) 
      .withObjectAccessHook(new HibernateUnproxyObjectAccessHook()) 
      .withMappingStyle(MappingStyle.BEAN) 
      .registerJaversRepository(javersSqlRepository) 
      .build(); 

    javersSqlRepository.ensureSchema(); 
} 
+0

您正在提前得出結論。 –

0

在Spring應用程序,例如Javers應註冊爲一個Spring bean。當txManager準備就緒時,JaVers使用@PostConstruct註釋和Spring調用ensureSchema()

見JaversTransactionalDecorator IMPL:

@PostConstruct 
public void ensureSchema() { 
    TransactionTemplate tmpl = new TransactionTemplate(txManager); 
    tmpl.execute(new TransactionCallbackWithoutResult() { 
     @Override 
     protected void doInTransactionWithoutResult(TransactionStatus status)  { 
      javersSqlRepository.ensureSchema(); 
     } 
    }); 
} 

在你的情況,因爲你已經在你的控制器中創建的Javers實例,而不是作爲一個Spring bean這種方法不叫。你應該配置你的應用程序爲文檔說 - https://javers.org/documentation/spring-integration/#jpa-entity-manager-integration