Сопоставление OneToOne с сущностью из нескольких владельцев - PullRequest
2 голосов
/ 16 марта 2012

Я новичок в JPA.У меня есть, на мой взгляд, очень простой пример, но у меня возникли проблемы с его реализацией.По сути, у меня есть сущность, которую я хочу «повторно использовать» в других сущностях.

У меня есть User с двумя полями - Home и Office.Каждый из них, в свою очередь, ссылается на Address, например:

@Entity
public class User extends Model {

    @Column 
    private String name;

    @OneToOne
    private Home home;

    @OneToOne
    private Office office;

}

@Entity
public class Home extends Model {

    @OneToOne
    private Address address;

    @OneToOne(mappedBy="home")
    private User user;

    // ...

}

@Entity
public class Office extends Model {

    @OneToOne
    private Address address;

    @OneToOne(mappedBy = "office")
    private User user;

    // ...
}

@Entity
public class Address extends Model {

    @Column
    private String line1;

    @Column 
    private String line2;

    @Column
    private String city;

    /*
     * Is this possible? Being owned by two entities?
     */


    @OneToOne(mappedBy="address")
    private Home home;

    @OneToOne(mappedBy="address")
    private Office office;

    // ...
}

Как мне этого добиться?


EDIT

Я изначально работалв это исключение:

org.hibernate.AnnotationException: @OneToOne or @ManyToOne on example.Home.address references an unknown entity: example.Address

Оказывается, один из классов импортировал аннотацию @Entity из org.hibernate вместо javax.persistence.После исправления этого исходное исключение исчезло ( это помогло мне точно определить проблему)

Однако теперь у меня есть новое исключение:

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: example.User.home -> example.Home

Надеюсьне совсем понимаю это точно.Должен ли я вызывать save объект Home, прежде чем сделать это на экземпляре User?

Ответы [ 2 ]

1 голос
/ 16 марта 2012

Можете сделать только 1 класс Пользователь:

@Entity public class User extends Model   
      {        
         @Column      
         private String name;

         @Embedded
         @AttributeOverrides({
            @AttributeOverride(name = "line1", column = @Column(name="column11")),
            @AttributeOverride(name = "line2", column = @Column(name="column21")),
            @AttributeOverride(name = "city", column = @Column(name="column31"))
         })     
         private Address homeAddress;        

         @Embedded
         @AttributeOverrides({
            @AttributeOverride(name = "line1", column = @Column(name="column12")),
            @AttributeOverride(name = "line2", column = @Column(name="column22")),
            @AttributeOverride(name = "city", column = @Column(name="column32"))
         })
         private Address officeAddress;

         // .. setters, getters
      }    

      @Embeddable 
      public class Address extends Model   
      {   
          private String line1;       
          private String line2;       
          private String city;  
         // .. getters, setters  
   }
1 голос
/ 16 марта 2012

Я исправил проблему, добавив атрибут cascade=CascadeType.ALL ко всем аннотациям @OnetoOne во всех сущностях.

Без этой аннотации мне пришлось бы save каждая принадлежащая сущность, прежде чем сохранить владеющую .Например, мне нужно сохранить Home перед сохранением User, которому принадлежит дом.

Добавление атрибута cascade к аннотации позаботится об этом за вас.Вам нужно только сохранить User, а Home и Address автоматически сохраняются для вас.

Этот пост помог мне решить проблему.

...