I new to JPA and learn from http://uaihebert.com/jpa-manytomany-unidirectional-and-bidirectional/
I have created two tables, one is Person
and another is Notebook
. If not mistaken, person_has_notebook
will be created if the code run successfully. (Correct me if I'm wrong as I am new to JPA).
Person
@Entity
@Table(name = "Person")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Person.findAll", query = "SELECT p FROM Person p")
, @NamedQuery(name = "Person.findById", query = "SELECT p FROM Person p WHERE p.id = :id")
, @NamedQuery(name = "Person.findByName", query = "SELECT p FROM Person p WHERE p.name = :name")
, @NamedQuery(name = "Person.findByCompName", query = "SELECT p FROM Person p WHERE p.compName = :compName")})
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Basic(optional = false)
@Column(name = "Name")
private String name;
@Basic(optional = false)
@Column(name = "CompName")
private String compName;
@ManyToMany
@JoinTable(name="person_has_notebooks", joinColumns={@JoinColumn(name="person_id")}, inverseJoinColumns={@JoinColumn(name="notebook_id")})
private List notebooks;
public List getNotebooks() {
return notebooks;
}
public void setNotebooks(List notebooks) {
this.notebooks = notebooks;
}
public Person() {
}
public Person(Integer id) {
this.id = id;
}
public Person(Integer id, String name, String compName) {
this.id = id;
this.name = name;
this.compName = compName;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCompName() {
return compName;
}
public void setCompName(String compName) {
this.compName = compName;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Person)) {
return false;
}
Person other = (Person) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "entity.Person[ id=" + id + " ]";
}
}
NoteBook
@Entity
@Table(name = "NoteBook")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "NoteBook.findAll", query = "SELECT n FROM NoteBook n")
, @NamedQuery(name = "NoteBook.findById", query = "SELECT n FROM NoteBook n WHERE n.id = :id")
, @NamedQuery(name = "NoteBook.findBySerialName", query = "SELECT n FROM NoteBook n WHERE n.serialName = :serialName")
, @NamedQuery(name = "NoteBook.findByRam", query = "SELECT n FROM NoteBook n WHERE n.ram = :ram")
, @NamedQuery(name = "NoteBook.findByHd", query = "SELECT n FROM NoteBook n WHERE n.hd = :hd")})
public class NoteBook implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Basic(optional = false)
@Column(name = "SerialName")
private String serialName;
@Basic(optional = false)
@Column(name = "Ram")
private int ram;
@Basic(optional = false)
@Column(name = "HD")
private int hd;
@ManyToMany(mappedBy="notebooks")
private List person;
public List getPersons() {
return person;
}
public void setPersons(List persons) {
this.person = persons;
}
public NoteBook() {
}
public NoteBook(Integer id) {
this.id = id;
}
public NoteBook(Integer id, String serialName, int ram, int hd) {
this.id = id;
this.serialName = serialName;
this.ram = ram;
this.hd = hd;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getSerialName() {
return serialName;
}
public void setSerialName(String serialName) {
this.serialName = serialName;
}
public int getRam() {
return ram;
}
public void setRam(int ram) {
this.ram = ram;
}
public int getHd() {
return hd;
}
public void setHd(int hd) {
this.hd = hd;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof NoteBook)) {
return false;
}
NoteBook other = (NoteBook) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "entity.NoteBook[ id=" + id + " ]";
}
}
ManyToMany1
public class ManyToMany1 {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("ManyToMany1PU");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
NoteBook noteA = new NoteBook();
noteA.setSerialNumber("A0123");
NoteBook noteB = new NoteBook();
noteB.setSerialNumber("B0123");
NoteBook noteC = new NoteBook();
noteC.setSerialNumber("C0123");
List notebooks = new ArrayList();
notebooks.add(noteA);
notebooks.add(noteB);
notebooks.add(noteC);
Person person = new Person();
person.setName("Zorro");
person.setNotebooks(notebooks);
em.persist(person);
em.getTransaction().commit();
}
}
Error
Exception Description: Predeployment of PersistenceUnit [ManyToMany1PU] failed.
Internal Exception: Exception [EclipseLink-7214] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The target entity of the relationship attribute [notebooks] on the class [class entity.Person] cannot be determined. When not using generics, ensure the target entity is defined on the relationship mapping.
at org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(PersistenceUnitLoadingException.java:127)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactoryImpl(PersistenceProvider.java:107)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:177)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
at manytomany1.ManyToMany1.main(ManyToMany1.java:27)
I have assigned mappedBy
to the weak side, but why still getting such errors ?
As the error states, when not using generics, you have to tell the provider which Entity you are referring to. Neil Stockton's answer below has an example of how to use generics. The javadoc has an example of specifying the target entity if you can't or don't want to use generics, as JPA has no idea what class you are referring to otherwise.
Otherwise, if you can use generics in the List, use Neils answer.
Why not just use generics as the message tells you?
and