Skip to main content

Persisting ManyToMany of Self

Please note these java.net forums are being decommissioned and use the new and improved forums at https://community.oracle.com/community/java.
1 reply [Last post]
LiverEatnJohnson
Offline
Joined: 2013-03-08

Hello everyone I am making my first real database application and need some help with this entity

/*
* Class      : Software Engenering and Design
* Project    : IGA LMS
* Members    : Jeremiah Johnson, Jason Keller, Justin Isom, Frank Halfred
* File       : TrainingClass.java
* Copyright  : (C) Jeremiah Johnson, Jason Keller, Justin Isom, Frank Halfred 2013
* Date       : Feb 11 2013
*/
package igalms.trainingclasses;

import java.io.Serializable;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

/**
* Entity Class for TrainingClass
* @author Johnson
*/
@Entity
@Table(name = "TRAINING_CLASSES", schema = "public")
public class TrainingClass implements Serializable {

  private static final long serialVersionUID = 1L;
  @Column(name = "ID")
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;
  //
  @Column(name = "TITLE", nullable = false, length = 50)
  private String title;
  //
  @Column(name = "DISCRIPTION", nullable = true)
  private String discription;
  //
  @Column(name = "RENUAL_INTERVAL", nullable = true)
  private Integer renualInterval;
  //
  @Column(name = "DUE_INTERVAL", nullable = true)
  private Integer dueInterval;
  //
  @ManyToMany
  @JoinTable(name = "CLASS_PREREQ",
          joinColumns =
          @JoinColumn(name = "PREREQ_ID"),
          inverseJoinColumns =
          @JoinColumn(name = "CLASS_ID"))
  private List<TrainingClass> parentList;
  //
  @ManyToMany
  @JoinTable(name = "CLASS_PREREQ",
          joinColumns =
          @JoinColumn(name = "CLASS_ID"),
          inverseJoinColumns =
          @JoinColumn(name = "PREREQ_ID"))
  private List<TrainingClass> childList;

  /**
   * Basic Constructor for TrainingClass
   */
  public TrainingClass() {
  }

  public List<TrainingClass> getParentList() {
    return parentList;
  }

  public void setParentList(List<TrainingClass> parentClassList) {
    this.parentList = parentClassList;
  }

  public List<TrainingClass> getChildList() {
    return childList;
  }

  public void setChildList(List<TrainingClass> childList) {
    this.childList = childList;
  }

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public String getDiscription() {
    return discription;
  }

  public void setDiscription(String discription) {
    this.discription = discription;
  }

  public Integer getRenualInterval() {
    return renualInterval;
  }

  public void setRenualInterval(Integer renualInterval) {
    this.renualInterval = renualInterval;
  }

  public Integer getDueInterval() {
    return dueInterval;
  }

  public void setDueInterval(Integer dueInterval) {
    this.dueInterval = dueInterval;
  }

  @Override
  public int hashCode() {
    int hash = 0;
    hash += (id != null ? id.hashCode() : 0);
    return hash;
  }

  @Override
  public boolean equals(Object object) {
    if (!(object instanceof TrainingClass)) {
      return false;
    }
    TrainingClass other = (TrainingClass) 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 "Classes.TrainingClasses[ id=" + id + " ]";
  }
}

As you can see it has a many to many of it's self if that makes any sense. I can add new classes to the list through a swing interface as long as the class doesn't have any parents. If it has parents i get a error like this.

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: An instance of a null PK has been incorrectly provided for this find operation.
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.getReference(UnitOfWorkImpl.java:5791)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.getReference(EntityManagerImpl.java:1275)
at igalms.trainingclasses.TrainingClassJpaController.create(TrainingClassJpaController.java:48)
at igalms.trainingclasses.TrainingClassController.saveTrainingClass(TrainingClassController.java:26)
at igalms.trainingclasses.AddTrainingClassDialog.saveBtnActionPerformed(AddTrainingClassDialog.java:245)
at igalms.trainingclasses.AddTrainingClassDialog.access$000(AddTrainingClassDialog.java:20)
at igalms.trainingclasses.AddTrainingClassDialog$1.actionPerformed(AddTrainingClassDialog.java:88)

Here is the code that I am using to add a new class.

private void saveBtnActionPerformed(java.awt.event.ActionEvent evt) {                                        
    if (titleFld.getText() != null || "".equals(titleFld.getText())) {
      TrainingClass trainingClass = new TrainingClass();
      trainingClass.setTitle(titleFld.getText());
      trainingClass.setDiscription(discriptionArea.getText());
      trainingClass.setDueInterval((Integer) dueSpinner.getValue());
      trainingClass.setRenualInterval((Integer) renuSpinner.getValue());
      //TODO: fix adding parents
      List<TrainingClass> prereq = new ArrayList<>();
      int[] parents;
      parents = parentList.getSelectedIndices();
      for (int id : parents) {
        prereq.add(trainingClassController.getClass(Long.valueOf(id)));
      }
      trainingClass.setParentList(prereq);
      trainingClassController.saveTrainingClass(trainingClass);
      setVisible(false);
    } else {
      JOptionPane.showMessageDialog(rootPane, "Classes must have a Title.");
    }
  }

I think it has something to do with the fact that the class that is being added with parents doesn't exist yet so it can't have parents, but I am not sure.

Any help would be great!!!
Thanks in advance.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
LiverEatnJohnson
Offline
Joined: 2013-03-08

This is a bit odd as far as I can tell my code is the same. I took my project home to my linux computer but same database, now I get this error

Exception in thread "AWT-EventQueue-0" javax.persistence.RollbackException: java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: Classes.TrainingClasses[ id=null ].
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:102)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:63)
at igalms.trainingclass.TrainingClassJpaController.create(TrainingClassJpaController.java:39)
at igalms.trainingclass.TrainingClassController.saveTrainingClass(TrainingClassController.java:26)
at igalms.trainingclass.AddTrainingClassDialog.saveBtnActionPerformed(AddTrainingClassDialog.java:242)
at igalms.trainingclass.AddTrainingClassDialog.access$000(AddTrainingClassDialog.java:21)
at igalms.trainingclass.AddTrainingClassDialog$1.actionPerformed(AddTrainingClassDialog.java:89)