punkyduck
punkyduck

Reputation: 719

Hibernate JPA: mappedBy reference exception

I want to map the following classes with Hibernate JPA:

enter image description here

My code looks like this:

   @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;
    }

Unfortunately, I get the following Exception:

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

As far as I understand the message, grid cannot be found in Membership. But as you can see in de code, there definitly is a variable named grid in the Membership class.

Does anybody has an idea whats going wrong?

Update: As suggested in the comments, I also tried to change the Membership Class by using IDClass or EmbeddedID. The EmbeddedID version looks like this:

 @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;
        }
    }

Unfortunately, I still get the same exception.

Update 2: I will rewrite all three classes from scratch tomorrow evening and update this post if that changes anything.

Upvotes: 2

Views: 3120

Answers (2)

Stefan K&#246;gl
Stefan K&#246;gl

Reputation: 4743

You should be able to use something like

@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>();
}

Upvotes: 1

wallenborn
wallenborn

Reputation: 4273

From the top of my head: shouldn't this be rather

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: What the exception is telling you is that your Grid class has a field named mem and that the entity represented by this field needs a grid field, but doesn't have one. Here is where your Grid.mem needs a grid field:

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

This mapping can only work if there is a property grid in Membership.class. If you hide the grid inside the IdClass, Grid.mem can't find it. You might try this:

@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
}

Upvotes: 0

Related Questions