ArrayList属性的延迟初始化失败(EclipseLink->Hibernate迁移)

ArrayList属性的延迟初始化失败(EclipseLink->Hibernate迁移),hibernate,jakarta-ee,eclipselink,wildfly,Hibernate,Jakarta Ee,Eclipselink,Wildfly,我将JavaEEWAR网站从Glassfish4迁移到WildFly 玻璃鱼使用日食,野蝇使用冬眠。我将Java服务器面与名为bean的CDI一起使用。我的一个bean直接调用dao类方法来检索类别对象。Category类有一些属性,其中一个是List商品。默认情况下,这是另一个表的延迟初始化商品。检索到Category对象,但在尝试使用延迟初始化的List商品时,持久性包为空,并引发以下错误: javax.servlet.ServletException: failed to lazily i

我将JavaEEWAR网站从Glassfish4迁移到WildFly

玻璃鱼使用日食,野蝇使用冬眠。我将Java服务器面与名为bean的CDI一起使用。我的一个bean直接调用dao类方法来检索类别对象。Category类有一些属性,其中一个是List商品。默认情况下,这是另一个表的延迟初始化商品。检索到Category对象,但在尝试使用延迟初始化的List商品时,持久性包为空,并引发以下错误:

javax.servlet.ServletException: failed to lazily initialize a collection of role: cz.pscheidl.velkoobchod.domain.Category.merchandise, could not initialize proxy - no Session
我想我知道这是什么问题。调用此对象时,名为EshopBean的@Named bean不提供任何事务。这在玻璃鱼身上不应该起作用,但不知怎的它起了作用。在Category对象中设置商品列表的初始化后,一切正常。在相关的命名查询中,JOIN-FETCH也是如此

EshopBean对象如下所示:

@Named
@ViewScoped
public class EshopBean implements Serializable {


    @Inject private CategoryDao categoryDao;
    @Inject private MerchandiseDao merchandiseDao;
    @Inject private ActiveSession activeSession;
    @Inject private OrderDao orderDao;
    @Inject private Logger logger;


    private List<Category> categoryList;
    private List<OrderItem> offeredMerchandise;


    @PostConstruct
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void updateOfferedMerchandise() {
        List<Category> allCateogries = categoryDao.findByOffered(true);
        offeredMerchandise = new ArrayList<>();
        categoryList = new ArrayList<>();

        allCateogries.parallelStream().filter(e -> {
        return !e.getMerchandise().isEmpty();
        }).forEach(e -> {
        categoryList.add(e);

        e.getMerchandise().parallelStream().filter(m -> {
            return m.isOffered();}).forEach(m -> {
            offeredMerchandise.add(createOrderItem(m));
            });

        });
    }
}
Category对象似乎忽略了以下方法:

@Entity
@NamedQueries(
        {
            @NamedQuery(name = "findCategoryByName", query = "SELECT c FROM Category c WHERE c.name = :name"),
            @NamedQuery(name = "findAllCategories", query = "SELECT c FROM Category c"),
            @NamedQuery(name = "categoryHasMerchandise", query = "SELECT COUNT(m) FROM Merchandise m WHERE m.category = :categoryId"),
            @NamedQuery(name = "findCategoryByOffered", query = "SELECT c FROM Category c WHERE c.offered = :offered")
        }
)
public class Category implements Serializable {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    @Column(unique = true)
    @Size(min = 1, max = 255)
    private String name;
    @Column(nullable = false)
    private boolean offered;
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    @JoinColumn(name = "CATEGORY_ID")
    public List<Merchandise> merchandise;
}
@Stateless
public class CategoryDaoImpl implements CategoryDao {
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public List<Category> findByOffered(boolean activity) {
        Query findByOfferedQuery = entityManager.createNamedQuery("findCategoryByOffered", Category.class);
        findByOfferedQuery.setParameter("offered", true);
        return findByOfferedQuery.getResultList();
    }
}
CategoryDaoImpl省略了一些方法:

@Entity
@NamedQueries(
        {
            @NamedQuery(name = "findCategoryByName", query = "SELECT c FROM Category c WHERE c.name = :name"),
            @NamedQuery(name = "findAllCategories", query = "SELECT c FROM Category c"),
            @NamedQuery(name = "categoryHasMerchandise", query = "SELECT COUNT(m) FROM Merchandise m WHERE m.category = :categoryId"),
            @NamedQuery(name = "findCategoryByOffered", query = "SELECT c FROM Category c WHERE c.offered = :offered")
        }
)
public class Category implements Serializable {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    @Column(unique = true)
    @Size(min = 1, max = 255)
    private String name;
    @Column(nullable = false)
    private boolean offered;
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    @JoinColumn(name = "CATEGORY_ID")
    public List<Merchandise> merchandise;
}
@Stateless
public class CategoryDaoImpl implements CategoryDao {
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public List<Category> findByOffered(boolean activity) {
        Query findByOfferedQuery = entityManager.createNamedQuery("findCategoryByOffered", Category.class);
        findByOfferedQuery.setParameter("offered", true);
        return findByOfferedQuery.getResultList();
    }
}
调用链的方法如下:EshopBean.updateOfferedMerchances->CategoryDaoImpl.findByOffered->return to EshopBean.updateOfferedMerchances。我猜两者都被注释为事务性的,findByOffered方法被注释为所需的。然而,WildFly中的Hibernate说,我认为它不需要相同的事务上下文


问题摘要:我想让merchnadise延迟初始化并更正会话问题,因此在EshopBean.updateOfferedMerchances方法中延迟初始化带有商品的包。我真的需要加入FETCH还是将Lazy初始化设置为false?如何正确设置事务以使此代码开始工作?

当应用程序从Glassfish迁移到Wildfly上时,会出现此问题。不幸的是,与EclipseLink不同,Wildfly的默认HibernateJPA实现不允许您在关闭上下文后获取惰性关系

许多解决方案建议使用即时抓取进行重构,但这不是一个好的解决方案,因为即时抓取会增加响应,并且通过重构数据库访问会给正在工作的应用程序带来风险

而是将Hibernate替换为EclipseLink,作为Wildfly中的JPA持久性提供者。实用程序类的集合将EclipseLink集成到Wildfly和

您需要做的是将eclipselink-2.6.0.jar或您正在使用的任何版本复制到[WILDFLY_HOME]/modules/system/layers/base/org/eclipse/persistence/main中,然后在同一文件夹中编辑module.xml以包含jar:

<resources>
   <resource-root path="jipijapa-eclipselink-1.0.1.Final.jar"/>
   <resource-root path="eclipselink-2.6.0.jar">           
      <filter>
         <exclude path="javax/**" />
      </filter>
   </resource-root>
</resources>

别忘了重新启动服务器。

加入获取将是正确的过程。关于你的第二个问题,我不明白你想问什么?