Spring Boot with Hibernate Search can't find org.hibernate.query.ParameterMetadata - spring-boot

I have a fairly straight forward Spring Boot 1.5.2 application using Hibernate Search. JPA stuff works just fine.
I get Caused by: java.lang.ClassNotFoundException: org.hibernate.query.ParameterMetadata when running a search.
The code looks somewhat like this. Used to run in Wildfly, but I'm migrating to Spring Boot.
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
QueryBuilder qb = fullTextEntityManager.getSearchFactory()
.buildQueryBuilder()
.forEntity(Customer.class)
.get();
org.apache.lucene.search.Query
luceneQuery = qb.keyword()
.wildcard()
.onField("primaryParty.firstName")
.andField("primaryParty.sureName")
.andField("customerNumber")
.matching(query.trim() + "*")
.createQuery();
javax.persistence.Query jpaQuery =
fullTextEntityManager.createFullTextQuery(luceneQuery, Customer.class);
List<Customer> result = jpaQuery.getResultList();
Hibernate Core 5.0.12 is pulled in via Spring Boot, but the class is not there.
According to this: https://cia.sourceforge.io/tattleTaleReport/jar/hibernate-search-orm-5.7.0.Final.jar.html
i should expect to find it in hibernate-search-orm 5.7.0.Final. But from what I can see this jar only contains the org.hibernate.search package and no org.hibernate.query package. Can't find the class in any other package in that jar either, but it exists in a number of other packages on the class path.
Is the problem
javax.persistence.Query
If so, what to use instead? Or is the problem elsewhere?

Hibernate Search 5.7.0.Final is only compatible with Hibernate ORM 5.2.3.Final and later.
You should either:
downgrade Hibernate Search to 5.6.1.Final
or upgrade Hibernate ORM to version 5.2.3.Final or later. With Spring Boot, I'm afraid you would have to use and unstable version of Spring Boot, namely 2.0.0.BUILD-SNAPSHOT
EDIT: actually, it seems you can use Hibernate ORM 5.2+ with Spring Boot 1.5; see this sample. Be careful to use 5.2.3.Final or later, though (the sample uses 5.2.0.Final, which won't work).
By the way, the link you provided only mentions org.hibernate.query because of OSGi support, which probably isn't relevant to you. It happens that hibernate-search-orm (the module integrating Hibernate Search to Hibernate ORM) both imports and re-exports the org.hibernate.query package, but it doesn't provide it itself.

I was getting the same issue due to using 5.7.0.Final jar and it was not compatible. This issue got resolved by changing downgrade jar version.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-orm</artifactId>
<version>5.6.1.Final</version>

Related

'org.springframework.boot.web.server.LocalServerPort' is deprecated

Since Spring boot 2.7.1, #LocalServerPort (in the package org.springframework.boot.web.server.LocalServerPort) is deprecated.
What can I use in stead of this annotation?
Import the below package in your spring boot 2.7.1. use #LocalServerPort for the below-mentioned package.
org.springframework.boot.test.web.server
You can read about it here in the link
Once go through you query again for the SQL error.
You may try using #Value("${server.port}") to get the port. One thing to note here is since Spring Boot release 2.7.0, #LocalServerPort is moved to the test jar because the Spring Boot team only intended that they be used for tests. However, what Puneet suggests will also work provided that you have the below dependency in your pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
You can also use an event listener to grab the port once the web server has started. Depending on what you're trying to do this might work, but be aware that they even fires after beans have been created.
#EventListener
void onWebInit(WebServerInitializedEvent event) {
int port = event.getWebServer().getPort();
}
The simplest approach here is to use either #Value("${server.port}") or what Puneet suggests. Use the import from the test jar. And having the above-mentioned dependency in your pom.xml is vital for this to work.
You can checkout the github issue related to this migration.
The org.springframework.boot.web.server.LocalServerPort is deprecated.
You can import org.springframework.boot.test.web.server.LocalServerPort

nodeBuilder() is removed by Elasticsearch, but still spring-data-elasticsearch documentation contains configuration which uses nodeBuilder()

I was following the Spring-Data-Elasticseach documentaion and was following the configuration as mentioned in the above link.
#Configuration
#EnableElasticsearchRepositories(basePackages = "org/springframework/data/elasticsearch/repositories")
static class Config {
#Bean
public ElasticsearchOperations elasticsearchTemplate() {
return new ElasticsearchTemplate(nodeBuilder().local(true).node().client());
}
}
Since import for nodeBuilder() is not mentioned in the documentation I assumed it from org.elasticsearch.node.NodeBuilder.* as mentioned in elasticsearch Java API.
But in the later releases, the API got changed and NodeBuilder no longer exists. So why/how the spring documentation still using the NodeBuilder?
If that's an issue with the documentation, what's the right configuration?
The dependencies I am using
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
with the boot version 2.1.1.RELEASE
This looks like a documentation issue. I've raise DATAES-574 to have that fixed.
With Spring Boot 2.1, the usual way to create a Client bean is to set a spring.data.elasticsearch.cluster-nodes property. Behind the scenes this will create the Client as a org.elasticsearch.client.transport.TransportClient instance.
You can also define that bean yourself if you so wish.
In the future, TransportClient is also going to been deprecated by Elasticsearch. At that point you'll need to use the higher level REST API. See https://jira.spring.io/browse/DATAES-407 for the details.

Hibernate spring.jpa.mapping-resources=hibernate.cfg.xml not read after Spring-Boot 2.1.0

Spring-Boot 2.0.8 adds the mappings by creating entities from the *hbm.xml files listed in spring.jpa.mapping-resources=hibernate.cfg.xml, Any release after that ignores the mapping file.
javax.persistence.metamodel.Metamodel metaModel = emf.getMetamodel();
Set<EntityType<?>> entityTypeSet = metaModel.getEntities();
Anyone have an idea what i missed in either migration guides?

Spring Infinispan - Setting expiry time for cached objects

We are currently using below. It's quite old, but cannot upgrade to higher version now
`
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-spring3</artifactId>
<version>6.4.0.Final-redhat-4</version>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-client-hotrod</artifactId>
<version>6.4.0.Final-redhat-4</version>
</dependency>
`
We have modified our code from something with a direct JDG implementation (as shown below) to SpringRemoteCacheManager in an XML based configuration file and are using Spring cache:advice to define cacheable, cahce-put, cache-evict methods.
See Current code where we have control to add expiry time. We want to do similar thing with Spring - Infinispan as well. With Spring - Infinispan we do not write any application code that puts/gets objects in/from cache as its handled by Spring annotations (#Cacheable / #CachePut)
Appreciate if anyone can provide any pointers
RemoteCache<Object, Object> cache = jdgRemoteCacheManager.getCache(cacheName);
cache.put(keyName, object, 15, TimeUnit.MINUTES);
Unfortunately Spring Cache support doesn't provide such methods (see the Javadocs). So it seems the only way is to use the RemoteCache API provided by Infinispan.
Perhaps you could implement your own #Cacheable annotation and implement all the functionality you need. But that's a Spring question really...

WildFly 10, JCache - method caching

i have simple application using Spring Boot. I wanted allow method caching with JSR107 - JCache. So with help of tutorial i put together this code :
#CacheResult(cacheName = "testpoc")
public Country getCountry(Integer id){
System.out.println("---> Loading country with code '" + id + "'");
return new Country(id, "X", "Title");
}
with this POM file
...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.4.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>1.4.0.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
...
(dependency 'spring-boot-starter-web' is there for simple REST service which call getCountry method)
Everything works like documentations says - method is invoked only once.
Now i wanted to try it on WildFly 10 application server
I have modified pom file :
excluded tomcat
exluded spring-boot-starter-cache
added infinispan-jcache (because i want to use cache configured / managed by wildfly in standalone/domain.xml)
Check pom file here on pastebin.
Problem is, that i am receiving following error :
Cannot find cache named 'java:jboss/infinispan/app-cache'
(i have tried to use both JNDI assigned and name to infinispan cache configured in wildfly).
Following code created Cache object (so i can used it) :
CacheManager cacheManager = Caching.getCachingProvider().getCacheManager();
Cache<String, String> cache = cacheManager.createCache("testpoc", new MutableConfiguration<String, String>());
Question :
It is possible to use JCache method caching on WildFly 10 using Infinispan managed by WildFly ?
Or Infinispan should be used for method caching like JCache, hence JCache has "more functionality" than Infinispan.
Thank you very much
PS :It is not problem for me to put whole code on github and post link - it is few lines of code ...
There are a couple of problems with your approach so let me go through them in steps.
At first you need to use proper Infinispan setup. Infinispan bits shipped with WF should be considered as internal or private. In order to use Infinispan in your app properly - either add org.infinispan:infinispan-embedded to your deployment or install Infinispan Wildfly modules. You can find installation guide here (it's a bit outdated but still, the procedure is exactly the same - unpack modules into WF and use Dependencies MANIFEST.MF entry).
Once you have successfully installed Infinispan (or added it to your app), you need to consider whether you want to use Spring Cache or JCache. If you're only interested in using annotations - I would recommend the former since it's much easier to setup (all you need to do is to add #EnableCaching to one of your configurations). Finally with Spring Cache you will create an Infinispan CacheManager bean. An example can be found here.
Final note - if you still need to use JCache - use this manual to setup Caching Provider.

Resources