Spring jpa很多很多懒人删除

时间:2017-06-26 22:42:41

标签: java mysql spring hibernate jpa

我使用的是Spring jpa和mysql,我在删除实体方面遇到了问题,如何以最佳方式进行操作?

我的实体用户:

@ManyToMany(cascade = CascadeType.REMOVE)
@JoinTable(name = "users_tasks",
        joinColumns = {@JoinColumn(name = "user_id")},
        inverseJoinColumns = {@JoinColumn(name = "task_id")})
private List<Task> tasks;

我的实体任务:

@ManyToMany(fetch=FetchType.LAZY, mappedBy = "tasks")
private List<User> users = new ArrayList<>();

删除userServiceImpl中的用户(我不确定这是否正确但是有效):

user.setTasks(Collections.emptyList());
userRepository.save(user);
userRepository.delete(user);

在taskServiceImpl中删除任务(它不起作用):

task.setUsers(Collections.emptyList());
taskRepository.save(task);
taskRepository.delete(task);

异常:

java.sql.SQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`testdb`.`users_tasks`, CONSTRAINT `FK7todmyl52eiddpi6hc2nfgvbs` FOREIGN KEY (`task_id`) REFERENCES `tasks` (`task_id`))

我的jpa配置:

@Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();    
dataSource.setDriverClassName(
env.getRequiredProperty("database.driver");
dataSource.setUrl(env.getRequiredProperty("database.url"));
dataSource.setUsername(env.getRequiredProperty("database.password"));
dataSource.setPassword(env.getRequiredProperty("database.username"));
return dataSource;
}

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setDataSource(dataSource());
    factory.setPackagesToScan("com.taskmanager");
    factory.setJpaVendorAdapter(vendorAdapter);
    factory.setJpaProperties(additionalProperties());
    return factory;
}

@Bean
public JpaTransactionManager transactionManager() {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
    return transactionManager;
}

@Bean
public DataSourceInitializer dataSourceInitializer(DataSource dataSource) {
    DataSourceInitializer initializer = new DataSourceInitializer();
    initializer.setDataSource(dataSource);
    initializer.setDatabasePopulator(databasePopulator());
    return initializer;
}

private Properties additionalProperties() {
    Properties properties = new Properties();
    properties.put("hibernate.dialect", env.getRequiredProperty("hibernate.dialect"));
    properties.put("hibernate.show_sql", env.getRequiredProperty("hibernate.show_sql"));
    properties.put("hibernate.hbm2ddl.auto", env.getRequiredProperty("hibernate.hbm2ddl.auto"));
    properties.put("hibernate.enable_lazy_load_no_trans",
            env.getRequiredProperty("hibernate.enable_lazy_load_no_trans"));
    return properties;
}

private DatabasePopulator databasePopulator() {
    ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
    populator.addScript(dataScript);
    return populator;
}

帮我找到最适合删除的解决方法,我的设置是否拼写正确?谢谢

1 个答案:

答案 0 :(得分:1)

在您的示例中,表 import os import re from datetime import datetime from airflow.models import BaseOperator from airflow.plugins_manager import AirflowPlugin from airflow.utils.decorators import apply_defaults from airflow.operators.sensors import BaseSensorOperator class ArchiveFileOperator(BaseOperator): @apply_defaults def __init__(self, filepath, archivepath, *args, **kwargs): super(ArchiveFileOperator, self).__init__(*args, **kwargs) self.filepath = filepath self.archivepath = archivepath def execute(self, context): file_name = context['task_instance'].xcom_pull( 'file_sensor_task', key='file_name') os.rename(self.filepath + file_name, self.archivepath + file_name) class OmegaFileSensor(BaseSensorOperator): @apply_defaults def __init__(self, filepath, filepattern, *args, **kwargs): super(OmegaFileSensor, self).__init__(*args, **kwargs) self.filepath = filepath self.filepattern = filepattern def poke(self, context): full_path = self.filepath file_pattern = re.compile(self.filepattern) directory = os.listdir(full_path) for files in directory: if re.match(file_pattern, files): context['task_instance'].xcom_push('file_name', files) return True return False class OmegaPlugin(AirflowPlugin): name = "omega_plugin" operators = [OmegaFileSensor, ArchiveFileOperator] 是关系的所有者,这就是为什么在更新用户的任务时Hibernate会删除任务列表。

通过在任务实体上设置连接表,可以使两个实体成为关系的所有者:

User

请注意反向cloumns是反转的,映射的是删除的,表名是相同的。

另一个值得一提的解决方法是通过使用@ManyToMany(fetch=FetchType.LAZY) @JoinTable(name = "users_tasks", joinColumns = {@JoinColumn(name = "task_id")}, inverseJoinColumns = {@JoinColumn(name = "user_id")}) private List<User> users = new ArrayList<>();

更改users_tasks fks,直接在数据库上管理级联