Announcement Announcement Module
Collapse
No announcement yet.
Error updating @OneToMany mapping Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Error updating @OneToMany mapping

    Hi All,
    I am stuck at a point where i am trying to update a @OneToMany mapping.

    Problem:
    I have 2 entities: Criteria and Tasks. A criteria can contain multiple tasks.

    Code:
    class Criteria {
     @OneToMany(mappedBy = "criteria", cascade = { CascadeType.PERSIST,
    			CascadeType.MERGE, CascadeType.REFRESH }, fetch = FetchType.LAZY)
    	@Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE,
    			org.hibernate.annotations.CascadeType.ALL,
    			org.hibernate.annotations.CascadeType.MERGE,
    			org.hibernate.annotations.CascadeType.PERSIST })
    	private Set<Task> tasks;
    }
    
    class Task {
    @ManyToOne
    	@JoinColumn(name = "CRITERIA_ID", nullable=false)
    	private Criteria criteria;
    }
    I am trying to update an existing Criteria with new set of tasks. This requires removing all existing tasks and adding new tasks.
    Here is how i am doing:
    Code:
                   criteriaDao.persist(criteria);
    		Set<Task> existingTasks=criteria.getTasks();
    		if(existingTasks != null) {
    			for (Task task : existingTasks) {
    				task.setCriteria(null);
    			}
    			criteria.setTasks(tasks);
                            //more code which sets criteria for each task - this works if i try to save new criteria with new tasks
    		}
    Hibernate is throwing an exception:

    Caused by: java.sql.BatchUpdateException: ORA-00001: unique constraint (CCA_DEV_5.TASK__UN) violated
    This exception is thrown because it didn't remove the existing tasks.

    If i only delete all the tasks, it works perfectly and removed all the tasks for the given criteria with below code:
    Code:
                    criteriaDao.persist(criteria);
    		Set<Task> existingTasks=criteria.getTasks();
    		if(existingTasks != null) {
    			for (Task task : existingTasks) {
    				task.setCriteria(null);
    			}
    		}
    I tried all options of using merge after adding new tasks and more stuff but nothing seems to work for me. I am badly stuck here and definately missing something very basic in Hibernate.

    Thanks in advance.!

  • #2
    NEVER use a set method to set a managed collection! This will break.

    Clear the collection and after that add the criteria.

    Comment


    • #3
      I could get this fixed by adding a line between:
      for (Task task : existingTasks) {
      task.setCriteria(null);
      }
      => session.flush();
      criteria.setTasks(tasks);

      This makes sure that the delete statements are executed before the inserts.

      Comment


      • #4
        Which still is, simply, the wrong way to do things. YOu should simply never set a managed collection to null (jpa providers replace the actual collection with their own implementation to do persistence management if you set this to null the collection still lives which can lead to all sorts of weird problems).

        Comment


        • #5
          Corrections... i am using it like-

          criteria.getTasks().clear();
          criteriaDao.flush();
          criteria.getTasks().addAll(tasks);

          My bad for ignoring that comment...

          Comment

          Working...
          X