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:
mvn
spring-boot:run
(succeeds) vs running java -jar <war-file>
(fails)?Potentially pertinent information:
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