Я запускаю приложение, основанное на версии сообщества демонстрационного сайта Broadleaf Commerce (горячий соус).
Чтобы поэкспериментировать с CI и вариантами развертывания, мы преобразовали стандартную загрузочную упаковку (банку) в warследуя документации broadleaf и spring .
После преобразования приложение запустится нормально, но кажется, что некоторые взаимодействия с базой данных (JPA) были прерваны (ошибки впоиск и обновления БД).
У меня есть несколько связанных вопросов:
- Требуются ли дополнительные настройки или соображения для инициализации / доступа к ресурсам JPA (через Hibernate) при преобразовании из jar вВойна выше того, что указано в приведенной выше документации пружины?
- В чем разница между выполнением через цель maven
mvn
spring-boot:run
(успешно) и бегом java -jar <war-file>
(неудачей)? - Специально связано сошибка, которую я вижу (скопированная ниже) относительно пути критериев JPA, я нашла это ТАК сообщение , предполагающее, чтоЭто может быть проблема с реализацией.Но вернемся к вопросу № 2: если это так, то почему будет важно, каким образом я запускаю приложение, если это проблема с кодом?
Потенциально важная информация:
- Я проверил, что БД отвечает через других клиентов.
Сообщение об ошибке:
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:
@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>
Класс статуса архива (согласно сообщению об ошибке)
@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();
}