2016-10-27 16 views
2

最新のSpringブートバージョンでJPA/Hibernateで動作するようにカスケード削除を試行した後の記事と記事の後に記事を読んでいます。私はあなたがHibernateの特定のカスケードを使用しなければならないことを読んだことがあります。私は彼らがちょうど動作しないが、それは混在した袋のようであることを読んだ。私が試したことはすべて動作しません。この関係は双方向です。JPAとHibernate Cascade DELETE OneToManyが動作しません

は動作しません。

@Entity 
public class Brand { 

    @OneToMany(mappedBy = "brand", orphanRemoval = true, fetch = FetchType.LAZY) 
    @Cascade({CascadeType.DELETE}) 
    @JsonManagedReference("brand-tax-rate") 
    private List<TaxRate> taxRates; 

} 

は動作しません。

@Entity 
public class Brand { 

    @OneToMany(mappedBy = "brand", cascade = CascadeType.REMOVE, orphanRemoval = true, fetch = FetchType.LAZY) 
    @JsonManagedReference("brand-tax-rate") 
    private List<TaxRate> taxRates; 

} 

何も前Brandを削除するTaxRatesを削除する以外に動作しますか?

私のテストは、次のようになります。参照用

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringBootTest(classes = {Application.class, SpringSecurityConfig.class}) 
@ActiveProfiles("test") 
@Transactional 
public class CascadeTests { 

    @Autowired 
    private BrandService brandService; 

    @Autowired 
    private TaxRateLoaderService taxRateLoaderService; 

    @Autowired 
    private TaxRateService taxRateService; 

    @Autowired 
    private TaxRateRepository taxRateRepository; 

    @Autowired 
    private BrandRepository brandRepository; 

    @Test 
    public void testCascadeWorks() throws Exception { 

     taxRateLoaderService.loadData(null, 10); 

     // if I uncomment this then I'm good 
     // but shouldn't have to if cascade works 
     //taxRateService.deleteAll(); 
     brandService.deleteAll(); 

     List<TaxRate> rates = Lists.newArrayList(taxRateRepository.findAll()); 
     List<Brand> brands = Lists.newArrayList(brandRepository.findAll()); 

     Assert.assertEquals(rates.size(), 0); 
     Assert.assertEquals(brands.size(), 0); 
    } 
} 

がエラー:org.h2.jdbc.JdbcSQLException:によって引き起こさ

参照整合性制約違反 :「FKC4BCIKI2WSPO6WVGPO3XLA2Y9:PUBLIC.TAX_RATE FOREIGN KEY(BRAND_ID)REFERENCES PUBLIC.BRAND(ID)(1) "; SQL文: ブランドからの削除where id =? [23503-192]

UPDATEは、次の手順を行うには、私のbrandService.deleteAll()方法を変更:

@Override 
public void deleteAll() { 
    Iterable<Brand> iter = this.brandRepository.findAll(); 
    iter.forEach(brand -> this.brandRepository.delete(brand)); 
} 

まだ動作しません。

更新2:テストでは問題が発生しているようです。カスケードは、アプリケーションを実行しても問題なく動作するようです。

+0

brandService.deleteAllは()のように何を求めていますか?コードを追加できますか? –

+0

'brandRepository.deleteAll()'はこれだけです。私のリポジトリはすべてCrudRepositoryインターフェイスです。 – Gregg

+0

結果は何ですか?例外?もしそうなら、SQLロギングをオンにして何が起きているのかを確認してください。 –

答えて

3

DDLレベルのカスケード削除を生成する@OnDeleteアノテーションを見てみたいと思います。

自動スキーマ生成(例:hbm2ddl)を使用している場合はON DELETE CASCADEFOREIGN KEYの定義に追加されます。ただし、hbm2ddlよりもFlyway is almost always a better choiceを使用してください。

あなたのマッピングは次のようになります。

@OneToMany(mappedBy = "brand", orphanRemoval = true, fetch = FetchType.LAZY) 
@OnDelete(action = OnDeleteAction.CASCADE) 
@JsonManagedReference("brand-tax-rate") 
private List<TaxRate> taxRates; 
+0

読者にちょっとしたメモ。これをうまく理解すれば、Hibernateを使用してスキーマを生成する場合、ON DELETE CASCADEがSQLテーブルの外部キーに追加されます。 – aalku

+1

そうです。 OPはテスト間でDBスキーマをクリアしたい。この[ブログ投稿](http://www.greggbolinger.com/truncate-all-tables-in-spring-boot-jpa-app/)をご覧ください。 –

+0

しかし、答えは質問している人だけではありません。私たちはここに来る人の答えを説明しようとするべきです。 – aalku

関連する問題