2017-02-28 3 views
0

1対多関係の2つのエンティティがあります。外部キーがnullであるため、関連する子エントリの挿入に失敗します。 でもテストで動作します。春のデータThymeleaf - 関連するレコード、外部キーnullを挿入できません

質問者が親に子を追加していないため、ほとんどの問題が解決しました。これは私のケースではありません。どんな助けにも感謝!

エラー

Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL into ("AIWA"."CAT_DT"."CAT_ID")

編集1:以下、詳細なエラーログを追加します。

2017-03-01 09:45:04 DEBUG JpaTransactionManager:759 - Initiating transaction commit 2017-03-01 09:45:04 DEBUG JpaTransactionManager:512 - Committing JPA transaction on EntityManager [[email protected]] 2017-03-01 09:45:04 DEBUG SQL:109 - insert into CAT (CATTYPE, ..., ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?) 2017-03-01 09:45:04 TRACE BasicBinder:81 - binding parameter [1] as [NUMERIC] - [200] 2017-03-01 09:45:04 TRACE BasicBinder:69 - binding parameter [2] as [VARCHAR] - [null] 2017-03-01 09:45:04 TRACE BasicBinder:81 - binding parameter [3] as [VARCHAR] - [1] 2017-03-01 09:45:04 TRACE BasicBinder:69 - binding parameter [4] as [VARCHAR] - [null] 2017-03-01 09:45:04 TRACE BasicBinder:69 - binding parameter [5] as [VARCHAR] - [null] 2017-03-01 09:45:04 TRACE BasicBinder:69 - binding parameter [6] as [VARCHAR] - [null] 2017-03-01 09:45:04 TRACE BasicBinder:81 - binding parameter [7] as [NUMERIC] - [1] 2017-03-01 09:45:04 TRACE BasicBinder:69 - binding parameter [8] as [VARCHAR] - [null] 2017-03-01 09:45:04 TRACE BasicBinder:81 - binding parameter [9] as [NUMERIC] - [182] 2017-03-01 09:45:04 DEBUG SQL:109 - insert into CAT_DT (CAT_ID, DESCR, LANGUAGE, NAME, SORTNAME, ID) values (?, ?, ?, ?, ?, ?) 2017-03-01 09:45:04 TRACE BasicBinder:69 - binding parameter [1] as [NUMERIC] - [null] 2017-03-01 09:45:04 TRACE BasicBinder:81 - binding parameter [2] as [VARCHAR] - [a] 2017-03-01 09:45:04 TRACE BasicBinder:81 - binding parameter [3] as [NUMERIC] - [1] 2017-03-01 09:45:04 TRACE BasicBinder:81 - binding parameter [4] as [VARCHAR] - [a] 2017-03-01 09:45:04 TRACE BasicBinder:69 - binding parameter [5] as [VARCHAR] - [null] 2017-03-01 09:45:04 TRACE BasicBinder:81 - binding parameter [6] as [NUMERIC] - [264] 2017-03-01 09:45:04 WARN SqlExceptionHelper:144 - SQL Error: 1400, SQLState: 23000 2017-03-01 09:45:04 ERROR SqlExceptionHelper:146 - ORA-01400: cannot insert NULL into ("CAT_DT"."CAT_ID")

2017-03-01 09:45:04 INFO AbstractBatchImpl:208 - HHH000010: On release of batch it still contained JDBC statements 2017-03-01 09:45:04 DEBUG JpaTransactionManager:898 - Initiating transaction rollback after commit exception

エンティティ

public class Cat{ 
    private List<CatDt> catDts = new ArrayList<CatDt>(); 

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "cat", cascade=CascadeType.ALL) 
    public List<CatDt> getCatDts() { 
     if(this.catDts==null){ 
      this.catDts = new ArrayList<CatDt>(); 
     } 
     return this.catDts; 
    } 

    public void setCatDts(List<CatDt> catDts) { 
     this.catDts = catDts; 
    } 
} 

public class CatDt{ 
    private Cat cat; 

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE) 
    @JoinColumn(name = "CAT_ID", nullable = false) 
    public Cat getCat() { 
     return this.cat; 
    } 

    public void setCat(Cat cat) { 
     this.cat = cat; 
    } 
} 

Thymeleafフォーム結果の

<ul th:each="item, stat: *{catDts}"> 
    <li> 
     <span th:text="#{front.cat.CatDt.no.label}">No</span> 
     <label th:text="${stat.count}">1</label> 
    </li> 
    <li> 
     <span th:text="#{front.cat.CatDt.name.label}">Name</span> 
     <input type="text" th:field="*{catDts[__${stat.index}__].name}" th:id="${'name-'+stat.index}"> 
    </li> 
    <li> 
     <span th:text="#{front.cat.CatDt.descr.label}">Description</span> 
     <input type="text" th:field="*{catDts[__${stat.index}__].descr}" th:id="${'descr-'+stat.index}"> 
    </li> 
    <li> 
     <span th:text="#{front.cat.CatDt.lang.label}">Language</span> 
     <input type="text" th:field="*{catDts[__${stat.index}__].language}" th:id="${'language-'+stat.index}"> 
    </li>  
</ul> 

HTMLフォーム

<form action="/aiwaweb/cat/create" method="post"> 
    <!-- Main info --> 
    <ul> 
     <li> 
      <span>Code</span> 
      <input id="code" name="code" value="" type="text">   
     </li> 
     <li> 
      <span>Type</span> 
      <select id="catType" name="catType"> 
       <option...>...</option> 
      </select> 
     </li> 
     <li> 
      <span>Status</span> 
      <select id="status" name="status"> 
       <option value="0">INACTIVE</option> 
       <option value="1">ACTIVE</option> 
      </select> 
     </li>   
    </ul> 

    <!-- Details -->  
    <ul> 
     <li> 
      <span>No.</span> 
      <label>1</label> 
     </li> 
     <li> 
      <span>Name</span> 
      <input id="name-0" name="catDts[0].name" value="" type="text"> 
     </li> 
     <li> 
      <span>Description</span> 
      <input id="descr-0" name="catDts[0].descr" value="" type="text"> 
     </li> 
     <li> 
      <span>Language</span> 
      <input id="language-0" name="catDts[0].language" value="" type="text"> 
     </li> 
    </ul> 
</form> 

編集2コントローラを作成してCatDatにCatを追加する(以前はCatDtをCatに追加していました)。この2つの方法の関係のリンクが解決するが、しなかったと期待した。

コントローラ

私がこれまで

  1. 私は(保存私のコントローラ上でデバッグする場合)、猫が一覧でCatDt子どもたちが、猫の性質を持っていなかった何
    @GetMapping({"/create"}) 
    public String create(ModelMap model){ 
        Cat cat = new Cat(); 
        List<CatDt> catDts = new ArrayList<CatDt>(); 
        CatDt catDt = new CatDt(); 
        catDt.setCat(cat); //this is the extra line added 
        catDts.add(catDt); 
        cat.setCatDts(catDts); 
        model.addAttribute("cat", cat); 
        return "cat/create"; 
    } 
    
    @PostMapping(value="/create", params={"save"}) 
    public String save(final Cat cat 
         , final BindingResult bindingResult, final ModelMap model){ 
        if(bindingResult.hasErrors()){ 
         return "cat/create"; 
        } 
        Cat updatedCat = catService.save(cat); 
        model.clear(); 
        return "redirect:/cat/create"; 
    } 
    

    CatDtの値はnullです。しかし、それを考えると来るかもしれません、おそらくそれはまだ猫が保存されていないので、nullでなければなりません。

ユニットテスト

@Test 
public void testCatSave(){ 
    Cat cat = new Cat(); 
    cat.setCode("11111"); 
    ...  
    //add cat details 
    List<CatDt> catDts = new ArrayList<CatDt>();   
    CatDt catDt = new CatDt(); 
    catDt.setCat(cat); 
    catDt.setName("Test"); 
    ... 
    catDts.add(catDt); 
    cat.setCatDts(catDts);   
    Cat catUpdated = catService.save(cat); 
} 

永続コンフィグ

public class PersistenceConfig { 
    @Autowired 
    private Environment env; 

    @Bean 
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() 
    { 
     HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 
     LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); 
     factory.setDataSource(dataSource()); 
     factory.setJpaVendorAdapter(vendorAdapter); 
     factory.setJpaProperties(hibernateProperties()); 
     factory.setPackagesToScan("ae.tbits.atn.aiwacore.common.model"); 
     return factory; 
    } 

    @Bean 
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) 
    { 
     JpaTransactionManager txManager = new JpaTransactionManager(); 
     txManager.setEntityManagerFactory(emf); 
     return txManager; 
    } 

    @Bean 
    public HibernateExceptionTranslator hibernateExceptionTranslator(){ 
     return new HibernateExceptionTranslator(); 
    } 

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

    private Properties hibernateProperties() { 
     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.format_sql", env.getRequiredProperty("hibernate.format_sql")); 
env.getRequiredProperty("hibernate.type")); 
     return properties;   
    }  
} 

Tにこれに続いて、しかしhttp://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#the-controller

+0

追加の編集1を追加して、もう少しログを表示しました。親と子の2組の挿入ステートメントを見ることができます。何とか_childが新しく挿入された親id_を取得していません。 _commit_や_flush_のような手作業で行う必要はありますか?はいの場合はどこで試してみましたが、私のmvcコードでエラーが発生しました(_no transaction in progress_)。私のサービスは単にRepoのCat.save()を呼び出します。テストは正常に実行されます。エンティティや設定の変更が必要ですか? –

答えて

0

[OK]を子レコードを保存していないので、最終的には私ができました解決する。何とか子供のcatDtsがcatオブジェクトに追加されていなかったことがわかります。

コントローラでsave()を手動で再割り当てして保存しました。

public String save(final Cat cat 
     , final BindingResult bindingResult, final ModelMap model){ 
    if(bindingResult.hasErrors()){ 
     logger.info("Binding result error in create(save)"); 
     return "cat/create"; 
    } 
    //manually reassign - start 
    List<CatDt> catDts = cat.getCatDts(); 
    for (CatDt catDt : catDts) { 
     catDt.setCat(cat); 
    } 
    cat.setCatDts(catDts); 
    //manually reassign - end 

    Cat updatedCat = catService.save(cat); //saveAndFlush 
    model.clear(); 
    return "redirect:/cat/create"; 

} 

これは働いていたが、私は何とか私のthymeleafフォームは、それがリンクされていませんので、正しく設定されているので、誰もが説明で投げるために歓迎されていなかったと思います。

ありがとうございました。

関連する問題