2

I have three classes, Site, GoupIP and IP

A Site has one or many GrouIPs. A GroupIP has one or many IPs.

Here is the code:

Site

@Entity
@Table(name = "site")
public class Site implements Serializable {
private Set<GroupIp> groups;

@OneToMany(mappedBy = "site", fetch = FetchType.EAGER, cascade =CascadeType.ALL)
public Set<GroupIp> getGroups() {
    return groups;
}

public void setGroups(Set<GroupIp> groups) {
    this.groups = groups;
}

}

GroupIP

@Entity
@Table(name = "groupip")
public class GroupIp implements Serializable {
private Set<Ip> ips;
private Site site;

@ManyToOne(cascade = CascadeType.MERGE)
@JoinColumn(name = "site_id")
public Site getSite() {
return site;
}

@OneToMany(mappedBy = "groupip", fetch = FetchType.EAGER, cascade =CascadeType.ALL)
public Set<Ip> getIps() {
    return ips;
}

public void setIps(Set<Ip> ips) {
    this.ips= ips;
}

}

IP

@Entity
@Table(name = "ip")
public class Ip implements Serializable {
private GroupIp groupIp;

@ManyToOne(targetEntity = GroupIp.class,cascade = CascadeType.MERGE)
@JoinColumn(name = "groupip_id", nullable=false)
public GroupIp getGroupIp() {
return groupIp;
}

public void setGroupIp(GroupIp groupIp) {
        this.groupIp = groupIp;
}

}

On GroupIp class, I m getting:

In attribute 'ips', the "mapped by" value 'groupip' cannot be resolved to an attribute on the target entity.

Whats wrong on my code ??

K Nizar
  • 71
  • 1
  • 5
  • Why are you using `@ManyToOne` in `GroupIP`? There is no need to use that because the `Site` class has defined that there is a one-to-many relationship, so it will create a table to map those rows. If you're trying to achieve a unidirectional relationship between your classes then you're doing it wrong. See [here](http://stackoverflow.com/questions/12038380/how-to-define-unidirectional-onetomany-relationship-in-jpa). – px06 Sep 15 '16 at 08:22
  • 1
    replace mappedBy = "groupip" by mappedBy = "groupIp" – Mr_Thorynque Sep 15 '16 at 08:22
  • @px06 where did he state that he wants the site-groupip relation to be unidirectional? Also note that if you want a bi-directional relation you need to map both sides but make one the owner of the relation. – Thomas Sep 15 '16 at 08:26
  • @Thomas maybe I haven't got enough experience with this but all the ways that I've come across using `OneToMany`, there should never be the need to create a `ManyToOne` on the same field..? If `Site` is the owner then we can just reference it by doing in `GroupIP`: `referencedColumnName` using again; `OneToMany` – px06 Sep 15 '16 at 08:31
  • @px06 I'd say that in most cases `OneToMany` is used with a bidirectional relation and the actual owner of the relation is the many side since that doesn't require an additional table. Thus you need to add `mappedBy` to `OneToMany` to tell JPA that the other side of the relation is the owner, i.e. only changes to the other side are persisted. And of course a bidirectional relation also requires the use of `ManyToOne` on the many side. JPA 2 introduced the mapping you described, i.e. making use of `@JoinColumn`, but again: the OP didn't state the relation should be unidirectional at all. – Thomas Sep 15 '16 at 08:59
  • @Thomas Thanks for clarifying, I wasn't aware that it could be used this way. – px06 Sep 15 '16 at 09:01
  • Thank you all, i resolved it by using @carborgar suggestion. But on the `HttpServletResponse` i dont get the Ips of the Groups !! – K Nizar Sep 15 '16 at 09:50

1 Answers1

4

The mappedBy name that you have to put in the relationship is the name of the class attribute, not the table name.

So put @OneToMany(mappedBy = "groupIp",... (note the uppercase) instead of @OneToMany(mappedBy = "groupip",...

carborgar
  • 171
  • 2
  • 7
  • Thak you its work. But on the `HttpServletResponse` i got the `Groups` of `site` but not `Ips`of the `Groups`. – K Nizar Sep 15 '16 at 09:53
  • I suppose that you're sending data from a HTML form. Take a look at http://stackoverflow.com/questions/24658195/trouble-passing-a-list-object-as-hidden-variable-from-jsp-to-a-servlet – carborgar Sep 15 '16 at 09:57