2017-04-04 97 views
0

我想實現空對象模式 Hibernate實體。如何用相關的空對象保存實體與休眠

讓我們假設我們有Person實體與Address字段。在其中一種情況下,人的地址必須在其他地方定義,可能沒有定義。

@Entity 
class Person { 

    String name; 

    @ManyToOne(targetEntity = Address.class) 
    IAddress address; 

    public Person(String name, IAddress address) { 
     this.name = name; 
     this.address = address; 
    } 
} 

interface IAddress { 

    String getCity(); 

    String getStreet(); 
} 

@Entity 
class Address implements IAddress { 

    @Id 
    private Integer id; 

    private String city; 

    private String street; 

    public Address(String city, String street) { 
     this.city = city; 
     this.street = street; 
    } 

    @Override 
    public String getCity() { 
     return city; 
    } 

    @Override 
    public String getStreet() { 
     return street; 
    } 
} 

class NullObjectAddress implements IAddress { 

    @Override 
    public String getCity() { 
     return "London"; 
    } 

    @Override 
    public String getStreet() { 
     return "Baker street"; 
    } 
} 

我試圖保存人

Person per1 = new Person("Jhon Doe", new Address("Huge village", "main street")); 
personRepository.save(per1); //that`s ok 

Person per2 = new Person("Jhon Doe", new NullObjectAddress()); 
personRepository.save(per2); //throws exception 

例外是:

org.springframework.orm.jpa.JpaSystemException:錯誤訪問用於字段[私人Address.id]由反射持久性屬性[Person#id]:NullObjectAddress @ 3638120f;嵌套異常是org.hibernate.property.access.spi.PropertyAccessException:錯誤訪問字段[私人java.lang.Int Person.id]通過對持久性屬性[人#標識]反射:NullObjectAddress @ 3638120f

+1

這是一個想法;只需將「地址」字段設置爲空即可......就像在普通Java中一樣。你的JPA提供者不能應付這個問題嗎?似乎它堅持認爲它必須是「目標實體」類型,不是嗎? –

回答

1

的簡單的方法是在getter和setter方法使用null的字段值和處理null對象:

@Entity 
class Person { 

    @ManyToOne(targetEntity = Address.class) 
    IAddress address; 

    public Person(String name, IAddress address) { 
     this.name = name; 
     setAddress(address); 
    } 

    public IAddress getAddress() { 
     return address == null ? NullObjectAddress.INSTANCE : address; 
    } 

    public void setAddress(IAddress address) { 
     this.address = address instanceof NullObjectAddress ? null : address; 
    } 
} 

但是,你仍然需要把它當作JPQL/HQL查詢,如可空您需要使用address is (not) null而不是address = :address,參數:address的值爲NullObjectAddress實例。