Я хочу удалить запись в базе данных, но зафиксировать ее в (существующей) истории.
Строка из основной таблица удаляется, но в таблице _audit история доступна для чтения. Кроме того, я хочу протоколировать пользователя и метку времени удаления в таблице revinfo. Поэтому я использую способ Hibernate Envers вместо написания собственной логики (например, мягкое удаление).
Проблема:
Код: Выделить всё
java.sql.SQLException: No database selected
В проекте есть два источника данных, но каждый из них предназначен для разных целей. Кроме того, «проблемный» источник данных имеет несколько схем.
application.properties
Код: Выделить всё
datasource2.datasource.jdbc-url=jdbc:mysql://1.2.3.4:3306?useLegacyDatetimeCode=false&serverTimezone=UTC&useSSL=false
# ...
spring.jpa.properties.hibernate.default_schema=mydatabase
spring.jpa.properties.hibernate.envers.default_schema=mydatabase
spring.jpa.properties.org.hibernate.envers.default_schema=mydatabase
#spring.jpa.properties.hibernate.ejb.interceptor=org.hibernate.envers.event.spi.EnversIntegrator
spring.jpa.properties.hibernate.envers.store_data_at_delete=true
hibernate.integration.envers.revision_listener=com.project.data_access.entities.UserRevisionListener
Код: Выделить всё
@Entity
@RevisionEntity(UserRevisionListener.class)
@Table(name = "revinfo", schema = "mydatabase")
public class CustomRevisionEntity extends DefaultRevisionEntity {
private static final long serialVersionUID = 123456789L;
@Column(name = "username")
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
Код: Выделить всё
public class UserRevisionListener implements RevisionListener {
@Override public void newRevision(Object revisionEntity) {
CustomRevisionEntity revision = (CustomRevisionEntity) revisionEntity;
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {
revision.setUsername(authentication.getName());
} else {
revision.setUsername("anonymous");
}
}
Код: Выделить всё
@Transactional(transactionManager = "customTransactionManager", rollbackForClassName = "java.lang.Exception")
public Boolean deleteSomeObject(Long id, String access_token, Authentication auth) {
// some checks
if (objectExists)
{
customRepo.deleteById(id);
return true;
}
return false;
}
Код: Выделить всё
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "customEntityManagerFactory",
transactionManagerRef = "customTransactionManager",
basePackages = {"com.project.repo"},
repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class)
@EnableJpaAuditing
public class myDBConfig {
// ...
@Bean(name = "customEntityManagerFactory")
@Primary
public LocalContainerEntityManagerFactoryBean customEntityManagerFactory(
EntityManagerFactoryBuilder builder, @Qualifier("dataSource") DataSource dataSource) {
return builder.dataSource(dataSource).packages("com.project.data_access.entities")
.persistenceUnit("datasource2").properties(getHibernateProperties())
.build();
}
private Map getHibernateProperties() {
Map props = new HashMap();
props.put("hibernate.default_schema", "mydatabase");
props.put("hibernate.hbm2ddl.auto", "none");
return props;
}
}
Код: Выделить всё
CREATE TABLE `revinfo` (
`REV` int NOT NULL AUTO_INCREMENT,
`REVTSTMP` bigint DEFAULT NULL,
`username` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
PRIMARY KEY (`REV`)
) ENGINE=InnoDB AUTO_INCREMENT=637 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
Какую конфигурацию мне не хватает? Должен ли я вместо этого использовать собственную стратегию аудита?
Подробнее здесь: https://stackoverflow.com/questions/792 ... only-multi