ClassCastException when changing a collection association to a set if @PreUpdate listener exists in Hibernate

Solution Verified - Updated -

Issue

  • An association is defined between two entities and a PreUpdate listener is used

    public class EmployeeListener {
        @PreUpdate
        void onPreUpdate(Object o) {
        }
    }
    
    @Entity
    @EntityListeners( EmployeeListener.class )
    public class Employee {
        ...
        @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
        protected Collection<Task> tasks;
        ...
    }
    
    @Entity
    public class Task {
        ...
    }
    
  • Though the association is defined to use collection/bag semantics, it is being assigned a set

    HashSet<Task> tasks = new HashSet<Task>();
    tasks.add(new Task("Some work"));
    employee.setTasks(tasks);
    entityManager.merge(employee);
    entityManager.flush();
    
  • A ClassCastException is raised during flush after the update of the association

    java.lang.ClassCastException: java.util.HashSet cannot be cast to org.hibernate.collection.spi.PersistentCollection
        at org.hibernate.event.internal.FlushVisitor.processCollection(FlushVisitor.java:43)
        at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:104)
        at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:65)
        at org.hibernate.event.internal.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:59)
        at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:166)
        at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:235)
        at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:94)
        at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:38)
        at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1483)
        at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1469)
    

Environment

  • Red Hat JBoss Enterprise Application Platform (EAP) 7
  • Hibernate 5

Subscriber exclusive content

A Red Hat subscription provides unlimited access to our knowledgebase, tools, and much more.

Current Customers and Partners

Log in for full access

Log In

New to Red Hat?

Learn more about Red Hat subscriptions

Using a Red Hat product through a public cloud?

How to access this content