2017-06-26 12 views
0

Spring jpaとmysqlを使用していますが、エンティティの削除に問題があります。Spring jpa many to many lazy delete

私のエンティティのユーザー:

@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; 
} 

私は除去のための最善の回避策を見つける助けて、私の設定が正しく入力されていますか?

+0

ON DELETE CASCADEを使用してusers_tasks FKSを変更することによって、あなたのデータベースに直接カスケードを管理することですか? – crizzis

+0

複数のユーザーが1つのタスクを実行できますが、そのタスクが1人のユーザーのみに適用され、そのユーザーが削除された場合、そのタスクは誰にも利用できなくなるため削除する必要があります –

+0

...これは決してカスケード削除その仕事をするには、手作業で手作業を取り除く必要があります – crizzis

答えて

1

例では、テーブルUserが関係の所有者です。そのため、ユーザーのタスクを更新すると、Hibernateはタスクのリストを削除します。これまでの周りの

一つの仕事は、タスクエンティティに結合テーブルを設定することにより、関係の所有者として、両方のエンティティを作ることです。

@ManyToMany(fetch=FetchType.LAZY) 
@JoinTable(name = "users_tasks", 
    joinColumns = {@JoinColumn(name = "task_id")}, 
    inverseJoinColumns = {@JoinColumn(name = "user_id")}) 
private List<User> users = new ArrayList<>(); 

によってマッピングされ、逆cloumnsが逆転していることに注意してくださいですテーブル名は同じです。

言及する価値がある別の回避策は、なぜあなたは*これまで* `@のManyToMany`の関連付けを削除カスケードしたい

+0

ありがとう、それは私のために働く –

+0

@alexuioあなたは答えとしてそれをマークすることができます、それは私の答えの投票セクションの下のチックです –

+0

はい、もちろん、助けてくれてありがとう –