ClassCastException, PersistentCollection, Hibernate & JPA

Verwendet man Hibernate (und JPA) kann es mitunter zu recht exotischen Fehlern kommen.
Ein Beispiel, zu dem ich bei google heute nicht einen einzigen Treffer gefunden habe ist folgende Exception:


...
Caused by: javax.persistence.RollbackException: Error while commiting the transaction
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:71)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(
JpaTransactionManager.java:438)
... 55 more
Caused by: java.lang.ClassCastException: java.util.HashSet
cannot be cast to org.hibernate.collection.PersistentCollection

at org.hibernate.event.def.FlushVisitor.processCollection(FlushVisitor.java:34)
...


Das tritt dann auf, wenn man wohlmeinend die Exposition der internen Repräsentation vermeiden wollte und beispielsweise so etwas hier auf einer persistenten Collection macht:

 @Entity
 public  class foo {
       private Set<AnotherEntity> _relatedEntites = new HashSet<AnotherEntity>();

     @OneToMany(cascade = {CascadeType.ALL }, fetch = FetchType.LAZY)
     @Column(name = "RELATED_ENTITIES")
      public Set<AnotherEntity> getRelatedEntities() {
            return new HashSet<AnotherEntity>(_relatedEntites)
     }
 }

Das: new HashSet() ist ein Fehler, da es aus der vorher erzeugten persistenten Collection wieder eine HashMap macht, die nicht persistiertbar ist.

Um die Manipulierbarkeit der Klasse zu vermeiden kann man stattdessen die @Immutable-Annotation verwenden:

 @Entity
 public  class foo {
       private Set<AnotherEntity> _relatedEntites = new HashSet<AnotherEntity>();

     @OneToMany(cascade = {CascadeType.ALL }, fetch = FetchType.LAZY)
     @Column(name = "RELATED_ENTITIES")
     @Immutable
      public Set<AnotherEntity> getRelatedEntities() {
            return _relatedEntites;
     }
 }

Dann klappt’s auch mit Hibernate.

This entry was posted on Tuesday, March 25th, 2008 at 23:06. Posted in: J2EE, JPA, System architecture, hibernate, java. You can follow any responses to this entry through the RSS 2.0feed. You can leave a response, or trackback from your own site.

Leave a Reply