6 Replies Latest reply on Feb 16, 2009 6:00 PM by binnyg

    EntityManager.persist() doesn't persist. Followed by org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: class java.lang.Long, got class org.hibernate.action.DelayedPostInsertIdentifier

    cmoerz.seam.ny-central.org

      I'm stuck in a problem I can't get my head around. I've got a class annotated with


      @TransactionAttribute(REQUIRES_NEW)
      



      I'm starting a conversation with


      @Begin(flushMode=FlushModeType.MANUAL)
      



      So I'm running inside a conversation and a Seam managed transaction. I'm creating a new entity instance that I keep in memory while the user manipulates the object and when it's time to saves everything to the database, I fail with


      javax.faces.FacesException: #{companyEdit.saveCompany}: javax.ejb.EJBTransactionRolledbackException: org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: class java.lang.Long, got class org.hibernate.action.DelayedPostInsertIdentifier
      



      The section of code that causes this is:


      for ( Employee e : this.persistList ) {
           entityManager.persist( e );
      }
           
      if ( !roomPersist.isEmpty() ) {
           for( Room r : roomPersist ) {
                entityManager.persist( r );
           }
      }
                
      entityManager.merge( this.getCompanyObj() );
      
      entityManager.flush();
      
      return "success";
      



      What's funny is, the persist for entity Employee works fine and is followed by insert statements on stdout while the persist call for entity Room doesn't do anything - no output, nothing.


      Both - Room and Employee use Long id field, annotated with


      @Id
      @GeneratedValue
      



      The backend is a MySQL database.


      So, as soon as I get to


      entityManager.merge( this.getCompanyObj() );
      



      where companyObj.rooms holds the rooms that suppossedly should have been persisted before. It then fails with above exception. I did put all the newly created room entities into the variable roomPersist so I know for which I need to call merge and for which I need to call persist. That works fine for the entity Employee, but fails for Room. It's really weird. I don't even reach the flush() call.


      Is there anyone who can tell me why the persist() call doesn't work on that entity? Is there a reason why persist might not persist an object but instead fill the id field with that temporary object??


      I also get


      12:00:58,754 ERROR [lifecycle] JSF1054: (Phase ID: INVOKE_APPLICATION 5, View ID: /company/edit.xhtml) Exception thrown during phase execution: javax.faces.event.PhaseEvent[source=com.sun.faces.lifecycle.LifecycleImpl@63b2ac]
      



      which doesn't really tell me anything. That error was mentioned in another post (see link below), but that post doesn't really help me:


      Post Link


      I'll post some more code below. Is there anything I'm doing wrong?? Please, anyone has an idea how to fix this? I'm completely confused why this isn't working.


      chris


      Room entity



      @SuppressWarnings("serial")
      @Entity
      @Table(name="Rooms")
      public class Room implements Serializable {
           private Long                    id;
           private List<Meeting>          bookings = new Vector<Meeting>();
           private String                    name;
           private Company                    company;
           private Integer                    maxCapacity;
      
           @OneToMany(mappedBy="location")
           public List<Meeting> getBookings() {
                return bookings;
           }
           public void setBookings(List<Meeting> bookedFor) {
                this.bookings = bookedFor;
           }
           
           @Transient
           public void addBooking( Meeting meeting ) {
                if ( this.getBookings().contains( meeting )) {
                     return;
                }
                this.getBookings().add( meeting );
                // just to be sure, set the meeting's location as well
                meeting.setLocation( this );
           }
           
           @Transient
           public void delBooking( Meeting meeting ) {
                if ( !this.getBookings().contains( meeting )) {
                     return;
                }
                this.getBookings().remove( meeting );
           }
           
           public Integer getMaxCapacity() {
                return maxCapacity;
           }
           public void setMaxCapacity(Integer maxCapacity) {
                this.maxCapacity = maxCapacity;
           }
           
           @NotNull
           @Length(max=256)
           public String getName() {
                return name;
           }
           public void setName(String name) {
                this.name = name;
           }
      
           @NotNull
           @ManyToOne
           public Company getCompany() {
                return company;
           }
           public void setCompany(Company company) {
                if ( (null != this.company) && ( this.company.equals( company ) )) {
                     return;
                }
                if ( (null == this.company) && (null == company )) {
                     return;
                }
                if ( (null != this.company) && ( !this.company.equals( company ))) {
                     this.company = null;
                     this.company.delRoom( this );
                }
                this.company = company;
                this.company.addRoom( this );
           }
           
           @Id
           @GeneratedValue
           public Long getId() {
                return id;
           }
           public void setId(Long id) {
                this.id = id;
           }
           
           @Transient
           @Override
           public String toString() {
                return getClass().getCanonicalName()+" ("+(null!=getId()?getId():"[null]/empty")+"): "+
                     (null!=getName()?getName():"[null]/empty")+" at "+
                     (null!=getCompany()?getCompany().getName():"[null]/empty");
           }
           
           @Transient
           @Override
           public int hashCode() {
                return toString().hashCode();
           }
           
           @Transient
           @Override
           public boolean equals( Object o ) {
                if ( !(o instanceof Room )) {
                     return false;
                }
                
                Room cmp = (Room) o;
                
                if ( ( null == getId() ) && ( null == cmp.getId() )) {
                     if ( ( null != getId() ) || ( null != cmp.getId() )) {
                          return false;
                     }
                     
                     return getCompany().equals( cmp.getCompany() ) &&
                               getName().equals( cmp.getName() );
                } else {
                     if ( ( null == getId() ) || ( null == cmp.getId() )) {
                          return false;
                     }
                     
                     if ( getId().longValue() != cmp.getId().longValue() ) {
                          return false;
                     }
                }
                
                return true;
           }
      }
      



      Company entity



      @Entity
      @Table(name="Companies")
      public class Company implements Serializable {
           private Long               id;
           private String               name;
           private String               phone;
           private String               fax;
           private Address               address;
           private List<Employee>     employees;
           private List<Room>          rooms;
           private boolean               deleted;
           
           @Id
           @GeneratedValue
           public Long getId() {
                return id;
           }
           public void setId(Long id) {
                this.id = id;
           }
           
           @NotNull
           @Length(max=256)
           public String getName() {
                return name;
           }
           public void setName(String name) {
                this.name = name;
           }
      
           @Length(max=64)
           public String getPhone() {
                return phone;
           }     
           public void setPhone(String phone) {
                this.phone = phone;
           }
      
           @Length(max=64)
           public String getFax() {
                return fax;
           }
           public void setFax(String fax) {
                this.fax = fax;
           }
           
           @Embedded
           public Address getAddress() {
                return address;
           }
           public void setAddress(Address address) {
                this.address = address;
           }
      
           @OneToMany(mappedBy="company", fetch=FetchType.LAZY)
           public List<Employee> getEmployees() {
                return employees;
           }
           public void setEmployees(List<Employee> employees) {
                this.employees = employees;
           }
                
           @OneToMany(mappedBy="company", fetch=FetchType.LAZY)
           public List<Room> getRooms() {
                return rooms;
           }
           public void setRooms(List<Room> rooms) {
                this.rooms = rooms;
           }
      
           /**
            * Add a room
            * @param room room to add
            */
           @Transient
           public void addRoom( Room room ) {
                if ((null != this.rooms) && (this.rooms.contains( room ))) {
                     return;
                }
                this.rooms.add( room );
                room.setCompany( this );
           }
           
           /**
            * Remove a room
            * @param room room to remove
            */
           @Transient
           public void delRoom( Room room ) {
                if ((null != this.rooms) && (this.rooms.contains( room ))) {
                     this.rooms.remove( room );
                     room.setCompany( null );
                }
           }
           
           /**
            * Adds the given person as an employee with the given role to this company. If the person's
            * company property is not set, it's being pointed to the chosen company.
            * 
            * @param person
            * @param role
            */
           @Transient
           public Employee addEmployee( Person person, Role role ) {
                Employee     newEmp = new Employee( person, this, role );
                
                if ( this.getEmployees().contains( newEmp )) {
                     return null;
                }
                this.getEmployees().add( newEmp );
                if ( person.getCompany() == null ) {
                     person.setCompany( this );
                }
                return newEmp;
           }
           
           /**
            * Remove an employee from a company. Practically, this function sets the end date
            * of an employee connection to now(). 
            * 
            * @param person
            * @param role
            */
           @Transient
           public void delEmployee( Person person, Role role ) {
                for ( Employee e : this.getEmployees()) {
                     if ( e.getPerson().getId() == person.getId() ) {
                          e.setEnd( new Date() );
                          
                          if ( person.getCompany() != null ) {
                               if ( person.getCompany().getId() == this.getId() ) {
                                    person.setCompany( null );
                               }
                          }
                     }
                }
           }
           
           @Transient
           @Override
           public int hashCode() {
                // TODO come up with a better hashCode function
                return toString().hashCode();
           }
           
           @Override
           @Transient
           public boolean equals( Object o ) {
                Company     cmp;
                if ( !(o instanceof Company) ) {
                     return false;
                }
                
                cmp = (Company) o;
                if ( ( null == cmp.getId() ) || (null == this.getId()) ) {
                     if ( ( null != cmp.getId() ) || ( null != this.getId() ) ) {
                          // one of the two was persisted before
                          return false;
                     }
                     
                     if ( !cmp.getName().equals( this.getName() )) {
                          return false;
                     }
                     if ( !cmp.getAddress().equals( this.getAddress() )) {
                          return false;
                     }
                } else {
                     if ( cmp.getId().longValue() != this.getId().longValue() ) {
                          return false;
                     }
                }
                
                return true;
           }
           
           @Transient
           @Override
           public String toString() {
                return getClass().getCanonicalName()+"("+(null!=this.id?this.id.toString():"[null]/empty")+") "+
                     (null!=this.name?this.name:"[null]/empty");
           }
           public boolean isDeleted() {
                return deleted;
           }
           public void setDeleted(boolean deleted) {
                this.deleted = deleted;
           }
           
           /**
            * Set the content of this company by copying the content from another company entity
            * @param original
            */
           @Transient
           public void duplicateFrom( Company original ) {
                this.setId( original.getId() );
                this.setAddress( new Address() );
                this.getAddress().setCity( original.getAddress().getCity() );
                this.getAddress().setCountry( original.getAddress().getCountry() );
                this.getAddress().setId( original.getAddress().getId() );
                this.getAddress().setState( original.getAddress().getState() );
                this.getAddress().setStreet( original.getAddress().getStreet() );
                this.getAddress().setZip( original.getAddress().getZip() );
                this.setEmployees( new Vector<Employee>() );
                this.getEmployees().addAll( original.getEmployees() );
                this.setFax( original.getFax() );
                this.setPhone( original.getPhone() );
                this.setName( original.getName() );
                this.setRooms( new Vector<Room>() );
                this.getRooms().addAll( original.getRooms() );
           }
      }
      



      Backing business bean



      @Stateful
      @Scope(ScopeType.CONVERSATION)
      @Name("companyEdit")
      @Restrict("#{identity.loggedIn}")
      @TransactionAttribute(REQUIRES_NEW)
      public class CompanyEditAction implements CompanyEdit {
           //@PersistenceContext(type=EXTENDED)
           @In
           private EntityManager          entityManager;
           @SuppressWarnings("unused")
           @PersistenceContext(type=EXTENDED)
           private EntityManager          em;
      
           @Logger
           private Log                         log;
           
           /*@In(required=false)*/ @Out(required=false)
           private Company                    companyObj;
           
           private Company                    original;
           
           @DataModel
           private List<Employee>          employees;
           @DataModelSelection("employees")
           private Employee               selEmployee;
           
           private List<Employee>          persistList = new Vector<Employee>();
           @DataModel
           private List<Room>               roomList;
           @DataModelSelection("roomList")
           private Room                    roomSelection;
           private List<Room>               roomPersist = new Vector<Room>();
           
           @In(create=true)
           private RoomDAO                    daoRoom;
           
           private String                    selTab;
           
           @In("#{messages['org.nycentral.labels.EnterName']}")
           private String                    nameValue;
           
           private boolean                    showAllEmployees = false;
           
           @In(create=true) @Out
           private PersonSelection          personSelection;
           
           @In
          FacesMessages                     facesMessages;
           
           @In
           private Events                     events;
           private static Role           roleEmployee;
            
           @Create
           public void init() {
                if ( log.isDebugEnabled() ) {
                     log.debug( this.getClass().getSimpleName() + " initialized." );
                }
                this.selTab = "contactTable";
           }
           
           @SuppressWarnings("unchecked")
           @Begin(flushMode=FlushModeType.MANUAL)
           public String editCompany(Company company) {
                //this.companyObj = company;
                this.original = company;
                this.companyObj = new Company();
                this.companyObj.duplicateFrom( original );
                
                this.roomList = this.companyObj.getRooms();
                
                if ( this.showAllEmployees ) {
                     this.employees = company.getEmployees();
                } else {
                     this.employees = this.entityManager.createQuery( "from Employee e where e.company=:cmpItem and " +
                               "e.start<=:sDate and ((e.end is null) or (e.end>:sDate))" ).
                                    setParameter("cmpItem", company ).
                                    setParameter("sDate", new Date() ).getResultList();
                     
                     // then we also need to check if there's anything not yet persisted...
                     if ( !this.persistList.isEmpty() ) {
                          this.employees.addAll( this.persistList );
                     }
                }
                this.selTab = "contactTable";
                return "success";
           }
           
           @End(beforeRedirect=true)
           public String delete() {
                this.original.setDeleted( true );
                entityManager.merge( original );
                entityManager.flush();
                
                events.raiseEvent( "org.nycentral.events.companyChanged" );
                events.raiseEvent( "org.nycentral.events.companyChangedObj", original );
                events.raiseTransactionSuccessEvent( "editCompany" );
                
                return "successDelete";
           }
           
           @End(beforeRedirect=true)
           @TransactionAttribute(REQUIRED)
           public String saveCompany() {
                if ( log.isDebugEnabled() ) {
                     log.debug( "Starting {0}.saveCompany()", this.getClass().getSimpleName() );
                     log.debug( "Company.address = {0}", this.getCompanyObj().getAddress() );
                     log.debug( "Company.address.country = {0}", this.getCompanyObj().getAddress().getCountry() );
                }
                
                for ( Employee e : this.getCompanyObj().getEmployees() ) {
                     // check if end dates are > start dates
                     if ( (e.getEnd() != null ) && ( e.getEnd().compareTo( e.getStart() ) < 0 )) {
                          // what now?
                          // TODO implement fix for faces message
                          this.facesMessages.addToControlFromResourceBundle( "empend", Severity.ERROR,
                                    "org.nycentral.labels.EndDateMustBeBiggerThanStart");
                          this.selTab = "employeeTable";
                          return null;
                     }
                }
                
                // persist everything that hasn't been persisted before
                for ( Employee e : this.persistList ) {
                     entityManager.persist( e );
                }
                
                if ( !roomPersist.isEmpty() ) {
                     for( Room r : roomPersist ) {
                          entityManager.persist( r );
                     }
                }
                
                // set the list of rooms to the current room list
                /*for ( Room r : this.roomList ) {
                     if ( this.roomPersist.contains( r )) {
                          continue;
                     }
                     
                     // merge / persist the rooms as necessary
                     entityManager.merge( r );
                }*/
      
                
                entityManager.merge( this.getCompanyObj() );
      
                entityManager.flush();
                events.raiseTransactionSuccessEvent("companySaved");
                // tell observers that company changed
                events.raiseEvent( "org.nycentral.events.companyChanged" );
                
                return "success";
           }
           
           public Company getCompanyObj() {
                return this.companyObj;
           }
           
           /**
            * add a new room
            */
           public void addRoom() {
                Room          room = new Room();
                
                companyObj.addRoom( room );
                
                //this.roomList.add( room );
                this.roomPersist.add( room );
           }
           
           /**
            * delete a room
            * @param room room to delete
            */
           public void delRoom( Room room ) {
                if ( ! this.roomList.contains( room )) {
                     return;
                }
                this.roomList.remove( room );
                
                if ( this.roomPersist.contains( room )) {
                     // not yet persisted rooms do not need to be handled via DAO
                     this.roomPersist.remove( room );
                     return;
                }
                
                // delete room for good
                daoRoom.deleteRoom( room );
           }
           
           /**
            * add a new employee
            */
           @SuppressWarnings("unchecked")
           public void addEmployee() {
                // create a list of people that can be added to this company
                // this includes everyone except the people who are already employees
                List<Person>           exclude = new Vector<Person>();
                List<Person>           people;
                Query                    q;
                
                if ( this.getEmployees().isEmpty() ) {
                     people = this.entityManager.createQuery( "from Person" ).getResultList();
                } else {
                     q = this.entityManager.createQuery( "select e.person from Employee e where e.company=:cmpItem and " +
                               "e.start<=:sDate and ((e.end is null) or (e.end>:sDate))" );
                     q.setParameter( "cmpItem", this.getCompanyObj() );
                     q.setParameter( "sDate", new Date() );
                     exclude = q.getResultList();
                     
                     // also make sure that we're taking anything not yet persisted into account
                     // -> that is handled afterwards (see if statement below)
                     /*if ( !this.persistList.isEmpty() ) {
                          for ( Employee e : this.persistList ) {
                               exclude.add( e.getPerson() );
                          }
                     }*/
                     
                     if ( !exclude.isEmpty() ) {
                          people = this.entityManager.createQuery("from Person p where p not in(:emps)").
                                                             setParameter("emps", exclude).getResultList();
                     } else {
                          // no exclusions - just take everyone from person list
                          people = this.entityManager.createQuery("from Person").getResultList();
                     }
                }
                
                if ( !this.persistList.isEmpty() ) {
                     // there are non-persistent additions; we need to remove that from the list
                     for ( Employee e : this.persistList ) {
                          people.remove( e.getPerson() );
                     }
                }
                
                // get employee role
                if ( roleEmployee == null ) {
                     roleEmployee = (Role) this.entityManager.createQuery("from Role where name=:rName").
                                                   setParameter("rName", "Employee").getSingleResult();
                }
                
                //people.removeAll( exclude );
                this.personSelection.reset();
                
                this.personSelection.setPersonList( people );
                
                this.personSelection.addListener( new IPersonSelectionListener() {
      
                     public void onSelectionCanceled( PersonSelection selection ) {
                          // do nothing                    
                     }
      
                     public void onSelectionDone( PersonSelection selection ) {
                          // get the selection and add them as employees
                          Employee          e;
                          
                          for ( Person p : selection.getSelectionResult() ) {
                               e = companyObj.addEmployee( p, roleEmployee );
                               // set the start date, else we can't switch between current-only/expired-included view via
                               // the checkbox, because the form always gets submitted triggering the validator
                               e.setStart( new Date() );
                               
                               // depending on the view we need to add this to the employee listing
                               // if we're not listing all entries, but only the current/valid ones
                               // we need to manually add it
                               if ( !employees.contains( e )) {
                                    employees.add( e );
                               }
                               
                               persistList.add( e );
                          }
                     }
                     
                });
           }
           
           /**
            * "Delete" employee by setting his/her end date to today
            */
           public void delEmployee( Employee e ) {
                if ( e == null ) {
                     return;
                }
                
                this.selTab = "employeeTable";
      
                if ( this.persistList.contains( e )) {
                     // we can remove this employee again, because it wasn't saved yet
                     this.getCompanyObj().getEmployees().remove( e );
                     if ( this.employees.contains( e )) {
                          this.employees.remove( e );
                     }
                     return;
                }
                
                e.setEnd( new Date() );
           }
           
           @End
           public void cancel() {
                if ( log.isDebugEnabled() ) {
                     log.debug( "{0} terminating.", this.getClass().getSimpleName() );
                }
                this.events.raiseEvent( "org.nycentral.events.companyReloadForce" );
           }
      
           public List<Employee> getEmployees() {
                return employees;
           }
      
           public Employee getSelEmployee() {
                return selEmployee;
           }
      
           public void setEmployees(List<Employee> employees) {
                this.employees = employees;
           }
      
           public void setSelEmployee(Employee selEmployee) {
                this.selEmployee = selEmployee;
           }
      
           public String getSelTab() {
                return selTab;
           }
      
           public void setSelTab(String selTab) {
                this.selTab = selTab;
           }
           
           @Destroy
           @Remove
           public void destroy() {
                if ( log.isDebugEnabled() ) {
                     log.debug( "Component {0} unloading.", this.getClass().getSimpleName() );
                }
           }
      
           public boolean isShowAllEmployees() {
                return showAllEmployees;
           }
      
           public void setShowAllEmployees(boolean showAllEmployees) {
                this.showAllEmployees = showAllEmployees;
           }
           
           /**
            * switch employee listing between current ones and all that were ever assigned/attached to
            * the company
            */
           public void switchAllEmployees() {
                this.showAllEmployees = ! this.showAllEmployees;
                
                this.editCompany( this.companyObj );
                this.selTab = "employeeTable";
           }
      
           public void setCompany(Company company) {
                this.companyObj = company;
           }
      
           public Room getRoomSelection() {
                return roomSelection;
           }
      
           public void setRoomSelection(Room roomSelection) {
                this.roomSelection = roomSelection;
           }
      
           public List<Room> getRoomList() {
                return roomList;
           }
      
           public void setRoomList(List<Room> roomList) {
                this.roomList = roomList;
           }
      }
      



      Exception in part (too long to post)



      12:00:58,723 ERROR [application] javax.ejb.EJBTransactionRolledbackException: org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: class java.lang.Long, got class org.hibernate.action.DelayedPostInsertIdentifier
      javax.faces.el.EvaluationException: javax.ejb.EJBTransactionRolledbackException: org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: class java.lang.Long, got class org.hibernate.action.DelayedPostInsertIdentifier
           at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
           at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
           at javax.faces.component.UICommand.broadcast(UICommand.java:387)
           at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:321)
           at org.ajax4jsf.component.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:296)
           at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:253)
           at org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:466)
           at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
           at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
           at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
           at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
           at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:177)
           at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:267)
           at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:380)
           at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:507)
           at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.HotDeployFilter.doFilter(HotDeployFilter.java:53)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
           at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
           at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
           at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
           at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182)
           at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:432)
           at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
           at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
           at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
           at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
           at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
           at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
           at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
           at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
           at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
           at java.lang.Thread.run(Unknown Source)
      Caused by: javax.ejb.EJBTransactionRolledbackException: org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: ...
      ...
      Caused by: org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: class java.lang.Long, got class org.hibernate.action.DelayedPostInsertIdentifier
           at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:86)
           at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878)
           at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:846)
           at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:557)
           at org.hibernate.type.EntityType.resolve(EntityType.java:379)
           at org.hibernate.type.EntityType.replace(EntityType.java:259)
           at org.hibernate.type.CollectionType.replaceElements(CollectionType.java:451)
           at org.hibernate.type.CollectionType.replace(CollectionType.java:518)
           at org.hibernate.type.TypeFactory.replace(TypeFactory.java:482)
           at org.hibernate.event.def.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:340)
           at org.hibernate.event.def.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:267)
           at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:120)
           at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53)
           at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677)
           at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661)
           at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665)
           at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:227)
           ... 130 more
      12:00:58,754 ERROR [lifecycle] JSF1054: (Phase ID: INVOKE_APPLICATION 5, View ID: /company/edit.xhtml) Exception thrown during phase execution: javax.faces.event.PhaseEvent[source=com.sun.faces.lifecycle.LifecycleImpl@63b2ac]
      12:00:58,754 WARN  [ExceptionFilter] handling uncaught exception
      javax.servlet.ServletException: #{companyEdit.saveCompany}: javax.ejb.EJBTransactionRolledbackException: org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: class java.lang.Long, got class org.hibernate.action.DelayedPostInsertIdentifier
      ...
      

        • 2. Re: EntityManager.persist() doesn't persist. Followed by org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: class java.lang.Long, got class org.hibernate.action.DelayedPostInsertIdentifier
          jkronegg

          Oups, wrong key.


          Your Room has a non-null Company, so you need to save first the company (so that it gets a key), then you can store the Room. The exception name (DelayedPostInsertIdentifier) suggests that the identifier (i.e. the key) will be obtained after the persist() operation (to be verified: I never seen this exception).

          • 3. Re: EntityManager.persist() doesn't persist. Followed by org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: class java.lang.Long, got class org.hibernate.action.DelayedPostInsertIdentifier
            cmoerz.seam.ny-central.org

            Hi Julien,


            thanks for the input; you are absolutely right - Company needs to be persisted first. In my cause though the Company being handled already exists in the database and was loaded when the component was initialized (via editCompany(...)).


            In the meantime I've figured out something else that makes the whole thing even more puzzling. The xhtml rendering the page splits the content across a couple of rich:tab elements. When I call the save function while remaining on the Rooms tab, I encounter a No transaction exception. When switching to another tab before pressing the save button, it works. It actually creates and persists any rooms created and returns successfully.


            I don't understand how that's even possible? Shouldn't the transaction be there during the whole conversation? Could there be something else that causes the transaction to either silently be rolled back or fail or even just vanish??


            The following exception occurs when it comes to flush() everything while remaining on the rooms tab.


            11:42:23,846 ERROR [application] javax.ejb.EJBException: javax.persistence.TransactionRequiredException: no transaction is in progress
            javax.faces.el.EvaluationException: javax.ejb.EJBException: javax.persistence.TransactionRequiredException: no transaction is in progress
                 at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
                 at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
                 at javax.faces.component.UICommand.broadcast(UICommand.java:387)
                 at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:321)
                 at org.ajax4jsf.component.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:296)
                 at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:253)
                 at org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:466)
                 at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
                 at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
                 at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
                 at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
                 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
                 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                 at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
                 at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)
                 at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                 at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
                 at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                 at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
                 at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                 at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
                 at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                 at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:177)
                 at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:267)
                 at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:380)
                 at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:507)
                 at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
                 at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                 at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58)
                 at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                 at org.jboss.seam.web.HotDeployFilter.doFilter(HotDeployFilter.java:53)
                 at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                 at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
                 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
                 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                 at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
                 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
                 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
                 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
                 at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182)
                 at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:432)
                 at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
                 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
                 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
                 at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
                 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
                 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
                 at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
                 at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
                 at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
                 at java.lang.Thread.run(Unknown Source)
            Caused by: javax.ejb.EJBException: javax.persistence.TransactionRequiredException: no transaction is in progress
                 at org.jboss.ejb3.tx.Ejb3TxPolicy.handleExceptionInOurTx(Ejb3TxPolicy.java:63)
                 at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:83)
                 at org.jboss.aspects.tx.TxInterceptor$RequiresNew.invoke(TxInterceptor.java:253)
                 at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                 at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:95)
                 at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                 at org.jboss.ejb3.stateful.StatefulInstanceInterceptor.invoke(StatefulInstanceInterceptor.java:83)
                 at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                 at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
                 at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:110)
                 at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                 at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
                 at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                 at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
                 at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                 at org.jboss.ejb3.stateful.StatefulContainer.localInvoke(StatefulContainer.java:206)
                 at org.jboss.ejb3.stateful.StatefulLocalProxy.invoke(StatefulLocalProxy.java:119)
                 at $Proxy160.saveCompany(Unknown Source)
                 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                 at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
                 at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
                 at java.lang.reflect.Method.invoke(Unknown Source)
                 at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
                 at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:31)
                 at org.jboss.seam.intercept.ClientSideInterceptor$1.proceed(ClientSideInterceptor.java:76)
                 at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
                 at org.jboss.seam.security.SecurityInterceptor.aroundInvoke(SecurityInterceptor.java:161)
                 at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                 at org.jboss.seam.ejb.RemoveInterceptor.aroundInvoke(RemoveInterceptor.java:43)
                 at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                 at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
                 at org.jboss.seam.intercept.ClientSideInterceptor.invoke(ClientSideInterceptor.java:54)
                 at org.javassist.tmp.java.lang.Object_$$_javassist_7.saveCompany(Object_$$_javassist_7.java)
                 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                 at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
                 at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
                 at java.lang.reflect.Method.invoke(Unknown Source)
                 at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:329)
                 at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:342)
                 at org.jboss.el.parser.AstPropertySuffix.invoke(AstPropertySuffix.java:58)
                 at org.jboss.el.parser.AstValue.invoke(AstValue.java:96)
                 at org.jboss.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
                 at com.sun.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:68)
                 at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
                 ... 51 more
            Caused by: javax.persistence.TransactionRequiredException: no transaction is in progress
                 at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:293)
                 at org.jboss.seam.persistence.EntityManagerProxy.flush(EntityManagerProxy.java:92)
            ...
                 at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                 at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
                 at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                 at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)
                 ... 93 more
            11:42:23,854 ERROR [lifecycle] JSF1054: (Phase ID: INVOKE_APPLICATION 5, View ID: /company/edit.xhtml) Exception thrown during phase execution: javax.faces.event.PhaseEvent[source=com.sun.faces.lifecycle.LifecycleImpl@12f24b]
            11:42:23,856 WARN  [ExceptionFilter] handling uncaught exception
            javax.servlet.ServletException: #{companyEdit.saveCompany}: javax.ejb.EJBException: javax.persistence.TransactionRequiredException: no transaction is in progress
                 at javax.faces.webapp.FacesServlet.service(FacesServlet.java:277)
                 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
                 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                 at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
                 at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)
                 at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                 at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
            ...
                 at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)
                 ... 93 more
            11:42:23,862 WARN  [ExceptionFilter] exception root cause
            javax.faces.FacesException: #{companyEdit.saveCompany}: javax.ejb.EJBException: javax.persistence.TransactionRequiredException: no transaction is in progress
                 at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
                 at javax.faces.component.UICommand.broadcast(UICommand.java:387)
                 at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:321)
                 at org.ajax4jsf.component.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:296)
                 at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:253)
                 at org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:466)
                 at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
                 at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
                 at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
                 at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
            ...
                 at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
                 at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                 at org.jboss.ejb3.entity.ExtendedPersistenceContextPropagationInterceptor.invoke(ExtendedPersistenceContextPropagationInterceptor.java:71)
                 at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                 at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
                 at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                 at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
                 at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                 at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)
                 ... 93 more
            11:42:23,865 WARN  [ExceptionFilter] running exception handlers
            



            chris

            • 4. Re: EntityManager.persist() doesn't persist. Followed by org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: class java.lang.Long, got class org.hibernate.action.DelayedPostInsertIdentifier

              Is seam managing your transactions?


              Since you are using @TransactionAttribute which is EJB specific, EJB container will manage your transactions and obviously Seam cannot manage CMTs.


              However, you can notify Seam about transaction boundaries with the following setting.


              <tx:ejb-transaction/>



              And I guess/believe your stateful session bean should implement SessionSynchronization interface.


              I will follow this thread and please let us know if you fix this issue. Thanks

              • 5. Re: EntityManager.persist() doesn't persist. Followed by org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: class java.lang.Long, got class org.hibernate.action.DelayedPostInsertIdentifier
                cmoerz.seam.ny-central.org

                Thanks for that hint; I just came across that setting in components.xml; that possible might have resolved the issue. However, I dropped everything yesterday and started rewriting everything from scratch and the resulting code doesn't throw the exception anymore. Just don't ask me why :)


                Still, I don't really understand the difference here between the Seam managed transactions and the CMTs. Does seam only support annotating a method with @Transactional or how do I tell Seam to keep a component managed inside a transaction until I either want to commit or rollback?


                Usually, for example I'd expect to be able to @End a save() method and rollback on a cancel() call, but how do I do that? There's no more @Rollback annotation as far as I can see. Or am I mixing something up here?


                What I've found so far is an old post at version 1.2.1, your suggestion to use ApplicationException (isn't that rather a hack, since it's not really an exception case?) and a seemlingly non-existent TransactionNotRequired annotation, which is also a hack.


                I really don't get how to tell Seam that a conversation is over, but the transaction should be rolled back. Or can I tell that to the EJB container somehow??


                Hope someone can shed some light on that.


                chris

                • 6. Re: EntityManager.persist() doesn't persist. Followed by org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: class java.lang.Long, got class org.hibernate.action.DelayedPostInsertIdentifier

                  CMTs are only used in EJBs and persistence managers live until your SFSB is active.
                  You cannot use it in POJOs


                  Seam managed persistence managers can be used both in EJBs and POJOs.
                  With seam managed persistence managers you have access to EL.


                  You can use a seam managed persistence context which is conversation scoped and persist the data at the end of conversation(i.e @End).


                  About ApplicationException, it really depends on how your application should behave when a business exception occurs. I doubt if it is considered a hack but I will let others comment on it. If this is not a desired approach you can always use transaction API to rollback( Transaction.instance().rollback()).


                  Dan Allen covered this topic in depth in his Seam in Action. I recommend this book.