2016-12-24 3 views
1

spring @ModelAttributeフォームバインディングではむしろ面倒な問題があります。私は、Policyクラスのネストされたクラスとしてフォームバインディングで使用される次のEntityクラスを持っています。ネストされたオブジェクトの空のフィールドでのスプリングフォームのバインディングの問題

@javax.persistence.Entity 
@Table(name = "entity") 
@XmlRootElement 
public class Entity implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Basic(optional = false) 
    @Column(name = "entity_id") 
    private Integer entityId; 

    @Basic(optional = false) 
    @NotNull 
    @Column(name = "entity_type") 
    private int entityType; 

    @Basic(optional = false) 
    @NotNull 
    @Size(min = 1, max = 2147483647) 
    @Column(name = "entity_name") 
    private String entityName; 

    public Entity() { 
    } 

    public Entity(Integer entityId) { 
     this.entityId = entityId; 
    } 

    public Entity(Integer entityId, int entityType, String entityName) { 
     this.entityId = entityId; 
     this.entityType = entityType; 
     this.entityName = entityName; 
    } 

    public Integer getEntityId() { 
     return entityId; 
    } 

    public void setEntityId(Integer entityId) { 
     this.entityId = entityId; 
    } 

    public int getEntityType() { 
     return entityType; 
    } 

    public void setEntityType(int entityType) { 
     this.entityType = entityType; 
    } 

    public String getEntityName() { 
     return entityName; 
    } 

    public void setEntityName(String entityName) { 
     this.entityName = entityName; 
    } 
} 

、トップレベルのクラスで私の問題、Policyクラスの主な関心と主な結合は次のとおりです。

@Entity 
@Table(name = "policy") 
@XmlRootElement 
public class Policy implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Basic(optional = false) 
    @Column(name = "policy_id") 
    private Integer policyId; 

    @Basic(optional = false) 
    @NotNull 
    @Size(min = 1, max = 2147483647) 
    @Column(name = "reference_number") 
    private String referenceNumber; 

    @JoinColumn(name = "adjuster_id", referencedColumnName = "entity_id", nullable = true) 
    @ManyToOne(optional = true) 
    private Entity adjusterId; 

    public Policy() { 
    } 

    public Policy(Integer policyId) { 
     this.policyId = policyId; 
    } 

    public Integer getPolicyId() { 
     return policyId; 
    } 

    public void setPolicyId(Integer policyId) { 
     this.policyId = policyId; 
    } 

    public String getReferenceNumber() { 
     return referenceNumber; 
    } 

    public void setReferenceNumber(String referenceNumber) { 
     this.referenceNumber = referenceNumber; 
    } 


    public Entity getAdjusterId() { 
     return adjusterId; 
    } 

    public void setAdjusterId(Entity adjusterId) { 
     this.adjusterId = adjusterId; 
    } 
} 

そして、これはModelAttribute注釈付きでとるコントローラのメソッドでありますビューバインディングからのポリシーパラメータ。

@RequestMapping(value = "/create", method = RequestMethod.POST) 
    public ModelAndView create(@ModelAttribute Policy p) { 
     policyService.create(p); 
     return new ModelAndView("viewName"); 
    } 

最後に、これはコードの形/ビューの一部である:

<form id="policyInformationForm" role="form" th:object="${policy}" th:action="@{${mode == 'CREATE'} ? '/policy/create' : '/policy/update'}" method="post"> 
         <div class="box-body"> 
          <div class="form-group"> 
           <label for="policyId">Policy Id</label> 
           <input type="text" th:field="*{policyId}" class="form-control" id="policyId" placeholder="" readonly="readonly" /> 
          </div> 

          <div class="form-group"> 
           <label for="referenceNumber">Policy Number (May change while saving!!!)</label> 
           <input type="text" th:field="*{referenceNumber}" class="form-control" id="referenceNumber" placeholder="Enter Policy Number" th:readonly="${mode == 'UPDATE'}" /> 
          </div> 

          <div class="form-group"> 
           <label for="adjusterName">Adjuster</label> 
           <div class="input-group"> 
            <input type="hidden" th:field="*{adjusterId.entityId}" class="form-control" id="adjusterId" /> 
            <input type="text" th:field="*{adjusterId.entityName}" class="form-control" id="adjusterName" placeholder="Enter Adjuster" /> 
            <div class="input-group-btn"> 
             <button id="adjusterSearchBtn" type="button" class="btn btn-success"><span class="glyphicon glyphicon-search"></span></button> 
             <button id="adjusterCreateBtn" type="button" class="btn btn-success"><span class="glyphicon glyphicon-plus"></span></button> 
            </div> 
           </div> 
          </div> 

         </div> 

         <div class="box-footer"> 
          <button type="submit" class="btn btn-primary">Submit</button> 
          <a th:href="@{'/policy/list'}" class="btn btn-warning">Cancel</a> 
         </div> 
        </form> 

iはフォームを送信するときに問題があります。 Springフォームバインディングは、フォームパラメータをPolicyクラスのそれぞれのフィールドにバインドしますが、アジャスターが選択されていない場合、すなわちadjusterId値の隠しフィールドが空白(アプリケーションに関しては完全に問題ありません)の場合、Springはすべてのフィールドを持つ新しいEntityクラスをインスタンス化します。ヌル値。これにより、ManyToOneリレーションシップとJPA検証のために、アプリケーションのJPA永続性部分に問題が発生します。

この問題を解決する方法に関するあらゆる指針。ビュー(フォームの非表示の入力フィールド)からのadjusterIdがnullの場合フォームバインディングは、nullフィールド値を持つ新しいEntityクラスをインスタンス化するべきではありません。代わりに、PolicyクラスのadjusterIdプロパティをnullに設定する必要があります。

私は既に同様の質問の多くを行っていますが、順番にそれらのほとんどは関連していません。そのうちの一つは、正確に事前にsame question which is unanswered

おかげで... contollerで

+0

私はIdToEntityConverterを結合春のフォームに問題を突き止めところで。既定のコンバータをオーバーライドする情報は非常に高く評価されます – Ahmet

答えて

3

、あなただけ行うことができます:

@RequestMapping(value = "/create", method = RequestMethod.POST) 
public ModelAndView create(@ModelAttribute Policy p) { 
    if (p.getAdjusterId().getEntityId() == null) { 
     p.setAdjusterId(null); 
    } 
    policyService.create(p); 
    return new ModelAndView("viewName"); 
} 
+0

私は既にこれを行っており、最も適切な回避策です。それは答えとして受け入れられる方法です。 IdToEntityConverterは、着信(フィールド)パラメータがnullであることを何らかの形で理解する必要があり、オブジェクトを構築すべきではないと考えています。 – Ahmet

+0

実際には解決策ではありません。それは解決策そのものです。 'IdToEntityConverter'をオーバーライドすることは非標準的な方法であり、この場合は努力する価値はありません。 'Policy'が関与するすべてのコントローラメソッドで同じロジック(' entityId'がnullであるかどうかをチェックする)を書こうとしない場合、メソッドレベルで 'ModelAttribute'アノテーションを使用できます。 [doc](http://docs.spring.io/spring/docs/4.1.x/spring-framework-reference/html/mvc.html#mvc-ann-modelattrib-methods)を見てください。 – sedooe

関連する問題