JBoss Community

Re: Services with missing/unavailable dependencies EntityManager

created by Evie White in JBoss AS7 Development - View the full discussion

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

Start a new discussion in JBoss AS7 Development at Community