2010-12-02 9 views
1

私は、アプリケーションで50のドメインクラスでBean検証を使用しています。 Spring MVCコントローラで@Validを使用しても問題なく何ヶ月も働いています。Spring MVC、@ValidとHibernateを使用したBean検証で奇妙な問題

突然、私はパフォーマンスを向上させるためにHibernateで多くのフィールドを "怠惰"にしました。私は、データがロードされていないため、セッションがクラッシュしているオブジェクトに、equals()メソッドが機能しなくなり、あらゆる種類の奇妙な問題に対処しなければなりませんでした。

私はSpring MVCのフォームのセッション属性にデータをロードI 午前は、ビューがそれを適切にレンダリングする場所現在、非常に奇妙な問題に遭遇してきたが、@Validに渡されたとき、それはすべてのフィールドをレポートデータが100%有効であってもエラーが発生する。ここで

<class name="jobprep.domain.educationfacility.EducationFacility" table="education_facility"> 
    <id name="id" column="education_facility_id" type="long"> 
     <generator class="native" /> 
    </id> 
    <property name="name" column="name"/> 
    <component name="address" class="jobprep.domain.educationfacility.Address"> 
     <property name="address" column="address"/> 
     <property name="postalCode" column="postal_code"/> 
     <many-to-one name="province" class="jobprep.domain.educationfacility.Province" column="province_id" /> 
    </component> 
    <property name="phoneNumber" column="phone_number"/> 
    <property name="isEnabled" column="is_enabled"/> 
    <property name="homepageViewable" column="homepage_viewable" /> 
    <property name="coursesCreated" /> 
    <many-to-one name="admin" class="jobprep.domain.user.Admin" column="admin_id" /> 
    <many-to-one name="director" class="jobprep.domain.educationfacility.Director" 
       column="director_id" cascade="all" /> 
    <bag name="teachers" inverse="true" cascade="all-delete-orphan" order-by="username asc"> 
     <key column="education_facility_id" /> 
     <one-to-many class="jobprep.domain.teacher.Teacher" /> 
    </bag> 
    <bag name="students" inverse="true" cascade="all-delete-orphan" order-by="username asc"> 
     <key column="student_education_facility_id" /> 
     <one-to-many class="jobprep.domain.student.Student"/> 
    </bag> 
    <bag name="ipRestrictions" inverse="true" cascade="all-delete-orphan"> 
     <key column="education_facility_id" /> 
     <one-to-many class="jobprep.domain.educationfacility.IpRestriction" /> 
    </bag> 
    <bag name="allowedModules" table="education_facility_to_module" 
     inverse="false" lazy="true"> 
     <key column="education_facility_id" /> 
     <many-to-many class="jobprep.domain.module.Module" column="module_id"/> 
    </bag> 
</class> 

は、コントローラの定義です:ここで
public class EducationFacility extends DomainObject { 

    /* Members */ 
    @NotEmpty(message = "{educationFacility.name.notEmpty}") 
    private String name; 

    @Valid 
    private Address address = new Address(); 

    @Pattern(message = "{educationFacility.phoneNumber.valid}", 
     regexp = "(\\()?(\\d){3}(\\))?(\\s|-)(\\d){3}(\\s|-)(\\d){4}") 
    private String phoneNumber = ""; 
    ... 
} 

は、休止状態の定義です。ここ

@RequestMapping(value = "/save", method = RequestMethod.POST) 
    public String save(@Valid EducationFacility educationFacility, BindingResult result, SessionStatus status) { 
     if(result.hasErrors()) { 
      return view("index"); 
     } else { 
      adminService.saveEducationFacility(educationFacility); 
      status.setComplete(); 

      return redirect("?complete=true"); 
     } 
    } 

春が追加されたエラーです。ここ

@Controller 
@RequestMapping("/myEducationFacility") 
@SessionAttributes("educationFacility") 
@PreAuthorize("hasRole('ROLE_DIRECTOR')") 
public class MyEducationFacilityController extends ControllerSupport { 
    .... 
} 

MVCの保存方法がありますバインディにSpringによってsave()が呼び出されたときの結果。これらは完全に間違っています:

{org.springframework.validation.BindingResult.educationFacility=org.springframework.validation.BeanPropertyBindingResult: 4 errors 
    Field error in object 'educationFacility' on field 'phoneNumber': rejected value [(519) 254-3678]; codes [Pattern.educationFacility.phoneNumber,Pattern.phoneNumber,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [educationFacility.phoneNumber,phoneNumber]; arguments []; default message [phoneNumber],[Ljavax.validation.constraints.Pattern$Flag;@29895454,(\()?(\d){3}(\))?(\s|-)(\d){3}(\s|-)(\d){4}]; default message [Must be of the form: ###-###-####] 
    Field error in object 'educationFacility' on field 'address.address': rejected value [Windsor]; codes [NotEmpty.educationFacility.address.address,NotEmpty.address.address,NotEmpty.address,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [educationFacility.address.address,address.address]; arguments []; default message [address.address]]; default message [Address may not be empty] 
    Field error in object 'educationFacility' on field 'name': rejected value [Catholic School Board]; codes [NotEmpty.educationFacility.name,NotEmpty.name,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [educationFacility.name,name]; arguments []; default message [name]]; default message [Name may not be empty] 
    Field error in object 'educationFacility' on field 'address.postalCode': rejected value [N9a 2a5]; codes [Pattern.educationFacility.address.postalCode,Pattern.address.postalCode,Pattern.postalCode,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [educationFacility.address.postalCode,address.postalCode]; arguments []; default message [address.postalCode],[Ljavax.validation.constraints.Pattern$Flag;@29895454,[a-zA-Z]\d[a-zA-Z](\s|-)\d[a-zA-Z]\d]; default message [Postal Code must be of the format: a#a-#a#], educationFacility=class jobprep.domain.educationfacility.EducationFacility{id=3}} 

ヘルプ?

答えて

4

ちょうど推測ですが、フィールドの代わりにゲッターに注釈注釈を設定しようとします。おそらく、フィールドの状態は、遅延ロードマジックのためにゲッターによって返された値と一致しないでしょう。

+0

私はそれを試してみましょう。他の2つのフォームでは、@Validが実際に働いているので(教育施設登録、管理者が新しい教育施設をシステムに追加/編集するとき)、それは変です。ディレクターが自分の教育施設を編集しているときに間違ったエラーを報告するだけです。そして、はい、私は、サービス層に呼び出すと、現在のユーザーセッションで1つを使用していないデータベースからそれをロードすることを確認します。この種のものは欲求不満の後ろにあり、私は休止状態を完全に放棄したい。 – egervari

+0

私はそれを吸って、director.educationFacilityをlazy = "false"にしました。それが働いたのはそれだけでした。愚かな休止状態。私は時々それが嫌いです。あなたが応答するのを悩ます唯一の人だったので、私はあなたに答えのクレジットを与えて、ポイントを得ることができます。 – egervari

2

実際問題は制約の配置です。それについて考えてみましょう。遅延読み込みは、プロキシとメソッドインターセプトを介して動作します。これは、エンティティのゲッターに制約を配置する場合にのみ機能します。プロキシは、メソッド呼び出しを介してアクセスする必要があります。制約の配置と同様にフィールドに直接アクセスすると、Validatorはプロキシ自体を検証します。またhttps://forum.hibernate.org/viewtopic.php?f=9&t=1005515http://opensource.atlassian.com/projects/hibernate/browse/HV-348