[jboss-dev-forums] [JBoss AS7 Development] - Re: Services with missing/unavailable dependencies EntityManager

Evie White do-not-reply at jboss.com
Mon Aug 8 13:34:06 EDT 2011


Evie White [http://community.jboss.org/people/yvette_white] created the discussion

"Re: Services with missing/unavailable dependencies EntityManager"

To view the discussion, visit: http://community.jboss.org/message/619950#619950

--------------------------------------------------------------
Scott & Raphael,

I know what is happening in my situation. In short, I am receiving a "*org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags*" error. Based on some research and then verification, I have found that this is a Hibernate issue that results from using a FetchType.EAGER on a @OneToMany entity attribute where the attribute is a *List* collection. To fix the issue, there are two things that can be done: 1) do not use FetchType.EAGER (use the default of LAZY) or 2) use a Set as the collection type for the @OneToMany instead of a List.

I will provide sample code below that will demonstrate the problem.

1. "TestDomain" - An Entity object that contains two collections. Both are @OneToMany that use an EAGER fetch strategy and are contained in List collections. (This is the problem: can't use EAGER or can't use List; use Set, for example.)

package foo.domain;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name="test")
public class TestDomain {

   @Id
   @GeneratedValue(strategy=GenerationType.IDENTITY)
   @Column(name="id")
   private Long id;

   @Column(name="name", length=255, nullable=false)
   private String name;

   @OneToMany(cascade={CascadeType.REMOVE}, fetch=FetchType.EAGER, mappedBy="test")
   private List<TestCommentDomain> comments;

   @OneToMany(cascade={CascadeType.REMOVE}, fetch=FetchType.EAGER, mappedBy="test")
   private List<TestPersonDomain> persons;

   public Long getId() {
      return id;
   }
   public void ListId(Long id) {
      this.id = id;
   }
   public String getName() {
      return name;
   }
   public void ListName(String name) {
      this.name = name;
   }
   public List<TestCommentDomain> getComments() {
      return comments;
   }
   public void ListComments(List<TestCommentDomain> comments) {
      this.comments = comments;
   }
   public List<TestPersonDomain> getPersons() {
      return persons;
   }
   public void ListPersons(List<TestPersonDomain> persons) {
      this.persons = persons;
   }
}


2. "TestCommentDomain" - An Entity object that is referenced by "TestDomain"

package foo.domain;
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.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name="test_comment")
public class TestCommentDomain {

   @Id
   @GeneratedValue(strategy=GenerationType.IDENTITY)
   @Column(name="id")
   private Long id;

   @ManyToOne(optional=false)
   @JoinColumn(name="test_id", nullable=false)
   private TestDomain test;

   @Column(name="comment", nullable=false)
   private String comment;

   public Long getId() {
      return id;
   }
   public void setId(Long id) {
      this.id = id;
   }
   public TestDomain getTest() {
      return test;
   }
   public void setTest(TestDomain test) {
      this.test = test;
   }
   public String getComment() {
      return comment;
   }
   public void setComment(String comment) {
      this.comment = comment;
   }
}


3. "TestPersonDomain" - A second Entity that is referenced by "TestDomain"

package foo.domain;
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.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name="test_person")
public class TestPersonDomain {

   @Id
   @GeneratedValue(strategy=GenerationType.IDENTITY)
   @Column(name="id")
   private Long id;

   @ManyToOne(optional=false)
   @JoinColumn(name="test_id", nullable=false)
   private TestDomain test;

   @Column(name="name", nullable=false)
   private String name;

   public Long getId() {
      return id;
   }
   public void setId(Long id) {
      this.id = id;
   }
   public TestDomain getTest() {
      return test;
   }
   public void setTest(TestDomain test) {
      this.test = test;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
}

4. "TestBean" - Remote interface for EJB stateless session bean.

package foo.bean;
import javax.ejb.Remote;
import foo.domain.TestDomain;

@Remote
public interface TestBean {
   public TestDomain find(Long id);
}

5. "TestBeanImpl" - EJB stateless session bean implementation. This is where the PersistenceContext is used.

package foo.bean.impl;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import foo.bean.TestBean;
import foo.domain.TestDomain;

@Stateless
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class TestBeanImpl implements TestBean {

   @PersistenceContext(unitName="bobo")
   private EntityManager manager;

   public TestDomain find(Long id) {
      return manager.find(TestDomain.class, id);
   }
}

6. persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence
    xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0">
    <persistence-unit name="bobo">
        <jta-data-source>java:jboss/datasources/testDS</jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <property name="show_sql" value="false" />
            <property name="format_sql" value="true" />
            <property name="use_sql_comments" value="false" />
        </properties>
    </persistence-unit>
</persistence>

7. portion of standalone.xml

| 
 | <subsystem xmlns="urn:jboss:domain:datasources:1.0"> |
| 
 | <datasources> |
| 
 | <datasource jndi-name="java:jboss/datasources/testDS" pool-name="testDS" enabled="true" jta="true" use-java-context="true" use-ccm="true"> |
| 
 | <connection-url> |
| 
 | jdbc:mysql://localhost:3306/bobo |
| 
 | </connection-url> |
| 
 | <driver> |
| 
 | mysql-connector-java-5.1.7-bin.jar |
| 
 | </driver> |
| 
 | <pool> |
| 
 | <min-pool-size> |
| 
 | 1 |
| 
 | </min-pool-size> |
| 
 | <max-pool-size> |
| 
 | 5 |
| 
 | </max-pool-size> |
| 
 | <prefill> |
| 
 | true |
| 
 | </prefill> |
| 
 | <use-strict-min> |
| 
 | false |
| 
 | </use-strict-min> |
| 
 | <flush-strategy> |
| 
 | FailingConnectionOnly |
| 
 | </flush-strategy> |
| 
 | </pool> |
| 
 | <security> |
| 
 | <user-name> |
| 
 | bobo_trx |
| 
 | </user-name> |
| 
 | <password> |
| 
 | Query123 |
| 
 | </password> |
| 
 | </security> |
| 
 | </datasource> |
| 
 | <drivers> |
| 
 | <driver name="h2" module="com.h2database.h2"> |
| 
 | <xa-datasource-class> |
| 
 | org.h2.jdbcx.JdbcDataSource |
| 
 | </xa-datasource-class> |
| 
 | </driver> |
| 
 | </drivers> |
| 
 | </datasources> |
| 
 | </subsystem> |


8. Packaged into a JAR:
foo\bean\TestBean.class
foo\bean\impl\TestBeanImpl.class
foo\domain\TestCommentDomain.class
foo\domain\TestDomain.class
foo\domain\TestPersonDomain.class
META-INF\MANIFEST.MF
META-INF\persistence.xml
log4j.properties


9. A portion of the stack trace:

11:53:52,662 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-8) MSC00001: Failed to start service jboss.persistenceunit."test.jar#bobo": org.jboss.msc.service.StartException in service jboss.persistenceunit."test.jar#bobo": Failed to start service
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1786)
    at org.jboss.msc.service.ServiceControllerImpl$ClearTCCLTask.run(ServiceControllerImpl.java:2291)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [:1.6.0_14]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [:1.6.0_14]
    at java.lang.Thread.run(Thread.java:619) [:1.6.0_14]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: bobo] Unable to build EntityManagerFactory
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:903)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:879)
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:73)
    at org.jboss.as.jpa.service.PersistenceUnitService.createContainerEntityManagerFactory(PersistenceUnitService.java:170)
    at org.jboss.as.jpa.service.PersistenceUnitService.start(PersistenceUnitService.java:80)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1765)
    ... 4 more
Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
    at org.hibernate.loader.BasicLoader.postInstantiate(BasicLoader.java:92)
    at org.hibernate.loader.entity.EntityLoader.<init>(EntityLoader.java:118)
    at org.hibernate.loader.entity.EntityLoader.<init>(EntityLoader.java:70)
    at org.hibernate.loader.entity.EntityLoader.<init>(EntityLoader.java:53)
    at org.hibernate.loader.entity.BatchingEntityLoader.createBatchingEntityLoader(BatchingEntityLoader.java:131)
    at org.hibernate.persister.entity.AbstractEntityPersister.createEntityLoader(AbstractEntityPersister.java:1976)
    at org.hibernate.persister.entity.AbstractEntityPersister.createEntityLoader(AbstractEntityPersister.java:1999)
    at org.hibernate.persister.entity.AbstractEntityPersister.createLoaders(AbstractEntityPersister.java:3248)
    at org.hibernate.persister.entity.AbstractEntityPersister.postInstantiate(AbstractEntityPersister.java:3234)
    at org.hibernate.persister.entity.SingleTableEntityPersister.postInstantiate(SingleTableEntityPersister.java:770)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:419)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1720)
    at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:77)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:894)
    ... 9 more

11:53:52,912 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-3) Stopped deployment test.jar in 6ms
11:53:52,912 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-3) Starting deployment of "test.jar"
11:53:52,912 INFO  [org.jboss.as.server.controller] (DeploymentScanner-threads - 1) Replacement of deployment "test.jar" by deployment "test.jar" was rolled back with failure message {"Failed services" => {"jboss.persistenceunit.\"test.jar#bobo\"" => "org.jboss.msc.service.StartException in service jboss.persistenceunit.\"test.jar#bobo\": Failed to start service"},"Services with missing/unavailable dependencies" => ["jboss.deployment.unit.\"test.jar\".jndiDependencyService missing [ jboss.naming.context.java.comp.test.test.TestBeanImpl.\"env/foo.bean.impl.TestBeanImpl/manager\" ]","jboss.deployment.unit.\"test.jar\".component.TestBeanImpl.START missing [ jboss.naming.context.java.comp.test.test.TestBeanImpl.\"env/foo.bean.impl.TestBeanImpl/manager\" ]"]}
11:53:52,912 INFO  [org.jboss.jpa] (MSC service thread 1-3) read persistence.xml for bobo
11:53:52,928 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-7) JNDI bindings for session bean named TestBeanImpl in deployment unit deployment "test.jar" are as follows:

    java:global/test/TestBeanImpl!foo.bean.TestBean
    java:app/test/TestBeanImpl!foo.bean.TestBean
    java:module/TestBeanImpl!foo.bean.TestBean
    java:global/test/TestBeanImpl
    java:app/test/TestBeanImpl
    java:module/TestBeanImpl
--------------------------------------------------------------

Reply to this message by going to Community
[http://community.jboss.org/message/619950#619950]

Start a new discussion in JBoss AS7 Development at Community
[http://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2225]

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/jboss-dev-forums/attachments/20110808/5e1129d1/attachment.html 


More information about the jboss-dev-forums mailing list