2012-03-26 3 views
2

Я хочу сопоставить следующие классы с Hibernate JPA:Hibernate JPA: mappedBy ссылка исключение

enter image description here

Мой код выглядит следующим образом:

@Entity 
    public class Grid{ 
     @Id 
     @GeneratedValue 
     private Long id; 
     @Column(unique=true) 
     private String name; 
     private String location; 
     private BigDecimal costsPerCPUMinute; 

     @OneToMany(mappedBy="grid") 
     private List<Membership> mem; 

      public List<Membership> getMem() { 
      return mem; 
      } 
      public void setMem(List<Membership> mem) { 
      this.mem = mem; 
      } 

@Entity 
public class User extends Person{ 
    @Column(nullable=false, unique=true) 
    private String username; 
    @Column(length=16,columnDefinition="BINARY(16)") 
    private byte[] password; 

    @OneToMany(mappedBy="user") 
    private List<Membership> mem; 

    public List<Membership> getMem() { 
     return mem; 
    } 
    public void setMem(List<Membership> mem) { 
     this.mem = mem; 
    } 


@SuppressWarnings("serial") 
@Entity 
public class Membership implements Serializable{ 

    private Date registration; 
    private Double discount;  
    @Id 
    @ManyToOne 
    private Grid grid; 
    @Id 
    @ManyToOne 
    private User user; 

    public Grid getGrid() { 
     return grid; 
    } 
    public void setGrid(Grid grid) { 
     this.grid = grid; 
    } 
    public User getUser() { 
     return user; 
    } 
    public void setUser(User user) { 
     this.user = user; 
    } 

К сожалению, я получаю следующее исключение:

Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: dst1.model.Membership.grid in dst1.model.Grid.mem 

Насколько я понимаю сообщение, сетка cann не может быть найдено в членстве. Но, как вы можете видеть в коде, определенно есть переменная с именем grid в классе Membership.

Есть ли у кого-нибудь идеи, что происходит не так?

Обновление: Как было предложено в комментариях, я также попытался изменить класс членства, используя IDClass или EmbeddedID. Версия EmbeddedID выглядит так:

@SuppressWarnings("serial") 
    @Entity  
public class Membership implements Serializable{ 

     private Date registration; 
     private Double discount;  
     @EmbeddedId 
     private MembershipPK membershipPK; 

     public Membership(){}; 

     public MembershipPK getMembershipPK() { 
      return membershipPK; 
     } 

     public void setMembershipPK(MembershipPK membershipPK) { 
      this.membershipPK = membershipPK; 
     } 

    @SuppressWarnings("serial") 
    @Embeddable 
    public class MembershipPK implements Serializable{ 
     @ManyToOne 
     private Grid grid; 
     @ManyToOne 
     private User user; 


     public Grid getGrid() { 
      return grid; 
     } 
     public void setGrid(Grid grid) { 
      this.grid = grid; 
     } 
     public User getUser() { 
      return user; 
     } 
     public void setUser(User user) { 
      this.user = user; 
     } 
    } 

К сожалению, у меня все те же исключения.

Обновление 2: Я завтра переписал все три класса с нуля и обновил этот пост, если это что-то изменит.

+0

Класс Membership имеет два @Id поля, это кажется неправильным. Я не думаю, что это правильный способ сопоставить составной первичный ключ. – Sebastien

+0

Ничего страшного с 2 полями Id, * пока сопровождается * IdClass. – DataNucleus

+0

Я попытался перейти от 2 полей id к EmbeddedId, но все тот же вопрос. – punkyduck

ответ

0

Из верхней части моей головы: не должно ли это быть довольно

public class MembershipId implements Serializable { 
    private Grid grid; 
    private User user; 

    // immutable constructor, getters, equals, and hashCode 
} 

@Entity 
@IdClass(MembershipId.class) 
public class Membership implements Serializable { 

    @Id @ManyToOne 
    private Grid grid; 

    @Id @ManyToOne 
    private User user; 

    // rest of class 
} 

Edit: Что исключение говорит вам, что ваш класс Сетка имеет поле с именем MEM и что лицо, представленное это поле требует поля сетки, но не имеет его. Вот где ваш Grid.mem нуждается в поле сетки:

@Entity 
public class Grid{ 
... 
    @OneToMany(mappedBy="grid") 
    private List<Membership> mem; 

Это отображение может работать только при наличии сетки недвижимости в Membership.class. Если вы спрячете сетку внутри IdClass, Grid.mem не сможет ее найти. Вы можете попробовать это:

@Embeddable 
public class MembershipId implements Serializable { 
    private Grid grid; 
    private User user; 

    // immutable constructor, getters, equals, and hashCode 
} 

@Entity 
public class Membership implements Serializable { 

    @EmbeddedId 
    private MembershipId id; 

    @ManyToOne 
    private Grid grid; 

    @ManyToOne 
    private User user; 

    // rest of class 
} 
+0

Я попробовал IdClass, а также EmbeddedId. К сожалению, все та же исключение. – punkyduck

1

Вы должны быть в состоянии использовать что-то вроде

@Embeddable 
public class MembershipId 
{ 
     protected Grid grid; 
     protected User user; 
} 

@Entity 
public class Membership { 
    @EmbeddedId 
    MembershipId id; 
} 

@Entity 
public class User { 
    @OneToMany(mappedBy="id.user") 
    private Set<Membership> memberships = new HashSet<Membership>(); 
} 
+0

это именно то, что я сделал. Но это не работает. – punkyduck

+0

Мне тоже не повезло с точкой («.»). Я должен был установить время для исправления этой проблемы и в итоге изменил схему db на сгенерированные (суррогатные) ключи, тем самым обойдя проблему составного FK-сопоставления-составного PK. –

+0

@skoegl.Спасибо за ответ, но у меня есть исключение, когда я пытаюсь сопоставить какое-то поле «Non Lazy Collection» на этом пути. Вы можете посмотреть http://stackoverflow.com/questions/23312951/jpa-and-hibernate-initialize-non-lazy-collections-error. Заранее спасибо. – Channa

Смежные вопросы