Spring Boot/JPA:为什么war转换会中断功能和/或JPA搜索? [英] Spring Boot / JPA: Why would war conversion break functionality and/or JPA searches?
问题描述
我正在运行基于社区版本的Broadleaf Commerce演示站点(辣酱)的应用程序.
为了试验配置项和部署选项,我们在 spring 文档.>
转换后,应用程序将正常启动,但似乎某些数据库(JPA)交互已中断(搜索和数据库更新错误).
我有几个相关问题:
- 从jar转换为war时,是否需要其他配置或注意事项来初始化/访问JPA(通过Hibernate)资源(通过上述Hibernate)?
- 通过maven目标
mvn spring-boot:run
运行(成功)与运行java -jar <war-file>
有什么区别 (失败)? - 与我看到的有关JPA标准路径的错误(下面复制)特别相关,我发现了这个
存档状态类(根据错误消息)
@Embeddable public class ArchiveStatus implements Serializable, SandBoxNonProductionSkip { @Column(name = "ARCHIVED") @AdminPresentation(friendlyName = "archived", visibility = VisibilityEnum.HIDDEN_ALL, group = "ArchiveStatus") protected Character archived = 'N'; public Character getArchived() { return archived; } public void setArchived(Character archived) { this.archived = archived; } }
产品类别(嵌入式存档状态)
@Entity @Inheritance(strategy = InheritanceType.JOINED) @javax.persistence.Table(name = "BLC_PRODUCT") //multi-column indexes don't appear to get exported correctly when declared at the field level, so declaring here as a workaround @org.hibernate.annotations.Table(appliesTo = "BLC_PRODUCT", indexes = { @Index(name = "PRODUCT_URL_INDEX", columnNames = {"URL", "URL_KEY"} ) }) @Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "blProducts") ... (BLC-specific overrides ommitted) ... public class ProductImpl implements Product, ProductAdminPresentation, Status, AdminMainEntity, Locatable, TemplatePathContainer { ... @Embedded protected ArchiveStatus archiveStatus = new ArchiveStatus(); ... }
DAO方法:
public List<SearchFacet> readAllSearchFacets(FieldEntity entityType) { CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery<SearchFacet> criteria = builder.createQuery(SearchFacet.class); Root<SearchFacetImpl> facet = criteria.from(SearchFacetImpl.class); criteria.select(facet); Path<Character> archived = facet.get("archiveStatus").get("archived"); criteria.where( builder.equal(facet.get("showOnSearch").as(Boolean.class), true), builder.or(builder.isNull(archived.as(String.class)), builder.notEqual(archived.as(Character.class), 'Y')), facet.join("fieldType") .join("indexField") .join("field") .get("entityType") .as(String.class) .in(entityType.getAllLookupTypes()) ); TypedQuery<SearchFacet> query = em.createQuery(criteria); query.setHint(QueryHints.HINT_CACHEABLE, true); query.setHint(QueryHints.HINT_CACHE_REGION, "query.Search"); return query.getResultList(); }
解决方案通过编译的jarfile运行DemoSite时,我发现了相同的错误.
看看这个线程: https://github.com/BroadleafCommerce/DemoSite/Issues/51
对于我来说,我必须在站点的pom.xml中包含
spring-instrument
依赖项,并使用-javaagent
参数指定其jar位置:$ java -Xmx1024m -javaagent:./path/to/spring-instrument.jar -jar site.jar
I am running a application based on the Community version of Broadleaf Commerce demo site (hot sauce).
To experiment with CI and deployment options, we have converted the stock spring boot packaging (jar) to war following the broadleaf and spring documentation.
After conversion, the application will start normally, but it seems that some database (JPA) interactions have been broken (errors on search and DB updates).
I have a few related questions:
- Is there additional configuration or considerations required to initialize/access JPA (via Hibernate) resources when converting from jar to war above what is specified in the spring documentation above?
- What is the difference between running via maven goal
mvn spring-boot:run
(succeeds) vs runningjava -jar <war-file>
(fails)? - Specifically related to the error I am seeing (copied below) regarding JPA criteria path, I found this SO post suggesting that it might be an implementation problem. But back to question #2, if that is the case, why would it matter which way I ran the application if it's a code issue?
Potentially pertinent information:
- I have verified that the DB is responding via other clients.
Error message:
2018-11-08 17:46:22.578 INFO 17053 --- [nio-8443-exec-7] o.h.cache.internal.StandardQueryCache : HHH000248: Starting query cache at region: query.Order 2018-11-08 17:46:22.820 ERROR 17053 --- [nio-8443-exec-7] .BroadleafSimpleMappingExceptionResolver : Error caught and handled.:05d420e6-69fc-4098-b085-2f8393a9ad7f org.springframework.dao.InvalidDataAccessApiUsageException: Unable to resolve attribute [archiveStatus] against path; nested exception is java.lang.IllegalArgumentException: Unable to resolve attribute [archiveStatus] against path at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:384) ~[spring-orm-4.3.18.RELEASE.jar!/:4.3.18.RELEASE] at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:246) ~[spring-orm-4.3.18.RELEASE.jar!/:4.3.18.RELEASE] ... Caused by: java.lang.IllegalArgumentException: Unable to resolve attribute [archiveStatus] against path at org.hibernate.ejb.criteria.path.AbstractPathImpl.unknownAttribute(AbstractPathImpl.java:120) ~[hibernate-entitymanager-4.1.11.Final.jar!/:4.1.11.Final] at org.hibernate.ejb.criteria.path.AbstractPathImpl.locateAttribute(AbstractPathImpl.java:229) ~[hibernate-entitymanager-4.1.11.Final.jar!/:4.1.11.Final] at org.hibernate.ejb.criteria.path.AbstractPathImpl.get(AbstractPathImpl.java:200) ~[hibernate-entitymanager-4.1.11.Final.jar!/:4.1.11.Final] at org.broadleafcommerce.core.search.dao.SearchFacetDaoImpl.readAllSearchFacets(SearchFacetDaoImpl.java:65) ~[broadleaf-framework-5.2.6-GA.jar!/:na] at org.broadleafcommerce.core.search.dao.SearchFacetDaoImpl$$FastClassBySpringCGLIB$$7573d5b3.invoke(<generated>) ~[broadleaf-framework-5.2.6-GA.jar!/:na] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.18.RELEASE.jar!/:4.3.18.RELEASE] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:736) ~[spring-aop-4.3.18.RELEASE.jar!/:4.3.18.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.18.RELEASE.jar!/:4.3.18.RELEASE] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.3.18.RELEASE.jar!/:4.3.18.RELEASE] ... 150 common frames omitted
Spring Boot Application configuration file:
@SpringBootApplication @EnableAutoConfiguration public class SiteApplication extends SpringBootServletInitializer { @Configuration @EnableBroadleafSiteAutoConfiguration public static class BroadleafFrameworkConfiguration {} @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(SiteApplication.class); } public static void main(String[] args) { SpringApplication.run(SiteApplication.class, args); } }
pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>org.broadleafcommerce</groupId> <artifactId>broadleaf-boot-starter-parent</artifactId> <version>5.2.6-GA</version> </parent> <artifactId>our-site</artifactId> <packaging>war</packaging> ... <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> ... </dependencies> ... </project>
Archive Status class (per the error message)
@Embeddable public class ArchiveStatus implements Serializable, SandBoxNonProductionSkip { @Column(name = "ARCHIVED") @AdminPresentation(friendlyName = "archived", visibility = VisibilityEnum.HIDDEN_ALL, group = "ArchiveStatus") protected Character archived = 'N'; public Character getArchived() { return archived; } public void setArchived(Character archived) { this.archived = archived; } }
Product Class (embeds Archive Status)
@Entity @Inheritance(strategy = InheritanceType.JOINED) @javax.persistence.Table(name = "BLC_PRODUCT") //multi-column indexes don't appear to get exported correctly when declared at the field level, so declaring here as a workaround @org.hibernate.annotations.Table(appliesTo = "BLC_PRODUCT", indexes = { @Index(name = "PRODUCT_URL_INDEX", columnNames = {"URL", "URL_KEY"} ) }) @Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "blProducts") ... (BLC-specific overrides ommitted) ... public class ProductImpl implements Product, ProductAdminPresentation, Status, AdminMainEntity, Locatable, TemplatePathContainer { ... @Embedded protected ArchiveStatus archiveStatus = new ArchiveStatus(); ... }
DAO method:
public List<SearchFacet> readAllSearchFacets(FieldEntity entityType) { CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery<SearchFacet> criteria = builder.createQuery(SearchFacet.class); Root<SearchFacetImpl> facet = criteria.from(SearchFacetImpl.class); criteria.select(facet); Path<Character> archived = facet.get("archiveStatus").get("archived"); criteria.where( builder.equal(facet.get("showOnSearch").as(Boolean.class), true), builder.or(builder.isNull(archived.as(String.class)), builder.notEqual(archived.as(Character.class), 'Y')), facet.join("fieldType") .join("indexField") .join("field") .get("entityType") .as(String.class) .in(entityType.getAllLookupTypes()) ); TypedQuery<SearchFacet> query = em.createQuery(criteria); query.setHint(QueryHints.HINT_CACHEABLE, true); query.setHint(QueryHints.HINT_CACHE_REGION, "query.Search"); return query.getResultList(); }
解决方案I've found the same error when I run DemoSite through compiled jarfile.
Take a look at this thread: https://github.com/BroadleafCommerce/DemoSite/issues/51
In my case, I had to include
spring-instrument
dependency in the site's pom.xml and specify its jar location with-javaagent
argument:$ java -Xmx1024m -javaagent:./path/to/spring-instrument.jar -jar site.jar
这篇关于Spring Boot/JPA:为什么war转换会中断功能和/或JPA搜索?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!