how to index a database already created using lucene hibernate search - java

I have a database with existing data that I want to index using Lucene Hibernate. When I create new data, Hibernate indexes it but the question is: how can I index all the old data in my database?
This is my persistence.xml file:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="persistenceUnit"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="hibernate.dialect" value="com.zodiac.qtp.domain.MySQL5CustomInnoDBDialect"/>
<!-- value="create" to build a new database on each run; value="update"
to modify an existing database; value="create-drop" means the same as "create"
but also drops tables when Hibernate closes; value="validate" makes no changes
to the database -->
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
<property name="hibernate.connection.charSet" value="UTF8" />
<property name="hibernate.connection.characterEncoding" value="UTF8"/>
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider"/>
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />
<property name="hibernate.generate_statistics" value="false" />
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory" />
<!-- Uncomment the following two properties for JBoss only -->
<!-- property name="hibernate.validator.apply_to_ddl" value="false" / -->
<!-- property name="hibernate.validator.autoregister_listeners" value="false" / -->
<property name="hibernate.search.default.directory_provider" value="org.hibernate.search.store.impl.FSDirectoryProvider"/>
<property name="hibernate.search.default.indexBase" value="C:\ZAM_DEV\QTPGenerator-repository\lucene-indexes-v2"/>
</properties>
</persistence-unit>
</persistence>

The short answer is that indexing is automatic: Hibernate Search will transparently index every entity each time it’s persisted, updated or removed through Hibernate ORM. Its mission is to keep the index and your database in sync, allowing you to forget about this problem.
However, when introducing Hibernate Search in an existing application, you have to create an initial Lucene index for the data already present in your database.
Once you have added the above properties and annotations, if you have existing data in the database you will need to trigger an initial batch index of your books. This will rebuild your index to make sure your index and your database is in synch. You can achieve this by using one of the following code snippets (see also Rebuilding the whole index):
Using an Hibernate Session to rebuild an index
FullTextSession fullTextSession = Search.getFullTextSession(session);
fullTextSession.createIndexer().startAndWait();
Using an EntityManager (JPA) to rebuild an index
FullTextEntityManager fullTextEntityManager =
Search.getFullTextEntityManager(entityManager);
fullTextEntityManager.createIndexer().startAndWait();
After executing the above code, you should be able to see a Lucene index under /var/lucene/indexes/example.Book.
The root of the storage path depends on the configuration property hibernate.search.default.indexBase we specified in the configuration step.
You could now inspect this index with Luke. It will help you to understand how Hibernate Search works: Luke allows you to inspect the index contents and structure, similarly to how you would use a SQL console to inspect the working of Hibernate ORM on relational databases.

The purpose of the persistence.xml file is to access entities from your DB. It really doesn't say much about the underlying indices, and you can't create DB indices using this file. To create your indices, you must logon to your DB server as an admin and create the indices using the appropriate CREATE INDEX commands.

Related

H2 database console: how to connect to an embedded H2 JPA database?

I have a couple of unit tests for an application's JPA layer. This JPA layer consists in JPA entities and a service providing the basic API required in order to persist the entities. The unit tets directly use the javax.persistence classes in order to handle the PersistenceManager. Then it tests the persistence API and I can see in the log the SQL statements to create tables and sequences, etc.
The relevant part of the persistence.xml file looks like:
<persistence-unit name="..." transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
...
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test"/>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.format_sql" value="false"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
...
I have downloaded H2 1.4.200, the Windows installer, and I installed it on Windows 10. Now using the H2 console I want to connect to the database and inspect the tables, sequences, etc. that were created automatically by Hibernate.
So, going to http://localhost:8082 I get the following:
But when I try to connect to my database, using the defined JDBC connection string, I get the following:
What am I doing wrong here ?
Many thanks in advance.
Nicolas
Finally, I've replaced H2 with Oracle.

How to solve "Using Hibernate built-in connection pool (not for production use!)" using JPA i.e. Hibernate EntityManager

I'm new to Hibernate and JPA in general.
I read a lot about this warning, but I still can't solve it.
The answers I read so far, said that it is necessary to have hibernate.cfg.xml in the project.
But I also read that:
If you are using JPA i.e. Hibernate EntityManager, you'll need the persistence.xml. So you generally don't need both as you use either Hibernate proprietary API or JPA.
(what is the purpose of two config files for Hibernate?)
Using persistence.xml I have this warning every time I use Hibernate.
This is my persistence.xml:
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="integration"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/db-name?autoReconnect=true"/>
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="root" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.id.new_generator_mappings"
value="true" />
</properties>
</persistence-unit>
</persistence>
I can't figure out what I'm doing wrong.
Thanks in advances
It is just a warning stating that you are using a built_in connection pool which is not a suitable solution in the production environment, you should use the application server connection pool in the production environment. depending on your application server you can setup database connection inside your application server then configure hibernate to use that connection.
But if you want to solve this problem without configuring the application server you can see this.

property tags in persistence.xml when using JPA

I am new to JPA and use Hibernate as the JPA provider. I came to know that we need META-INF/persistence.xml configuration file.
I successfully created a simple Java program to persist data in DB using JPA.
All fine, doubts started when I looked into the persistence.xml file to understand it better.
Sample below:
<persistence-unit name="test-jpa" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.url" value="jdbc:h2:tcp://localhost/~/test"/>
<property name="hibernate.connection.username" value="sa" />
<property name="hibernate.connection.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
The following is the Java code for reading the configuration:
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("test-jpa");
The following are the doubts:
How do we know that Hibernate is the JPA provider? Is it inferred by seeing the property tags in the file?
In config file, there are many <property> tags, are they pre-defined which can appear in the file (for a given JPA provider) or can we randomly add any property? who reads those <property> tags?
A JPA provider would provide documentation that would tell you all of that. Doesn't yours? I'd be surprised.
You should either have a <provider> element in the persistence-unit to define which provider to use, or it would use the default for the environment that you are running in (in JavaSE you would need to have 1 and only one JPA provider in the CLASSPATH, in JavaEE the server would have its own default).
They are provider-specific. Any properties that are prefixed javax.persistence would be JPA STANDARD. The first 4 of those posted have javax.persistence variants that you should have used instead.

Can it lead to problems while using the same Hibernate managed database for multiple projects?

I'm using Wildfly with Hibernate and I will have two different projects accessing the same database. Each project has its own persistence.xml, but the datasources within the persistence.xml are the same. Currently I have one project with these datasources. This looks like this:
Project A:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="MyProjectPersistenceUnit" transaction-type="JTA">
<jta-data-source>java:jboss/datasources/myprojectDS</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="UTF-8" />
<property name="hibernate.connection.charSet" value="UTF-8" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
</properties>
</persistence-unit>
<persistence-unit name="MyProjectLoggingUnit" transaction-type="RESOURCE_LOCAL">
<non-jta-data-source>java:jboss/datasources/myprojectDS</non-jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="UTF-8" />
<property name="hibernate.connection.charSet" value="UTF-8" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
</properties>
</persistence-unit>
</persistence>
The additional project's persistence.xml will look like this:
Project B:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="MyProjectLoggingUnit" transaction-type="JTA">
<jta-data-source>java:jboss/datasources/myprojectDS</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="UTF-8" />
<property name="hibernate.connection.charSet" value="UTF-8" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
</properties>
</persistence-unit>
</persistence>
The first project uses both JTA and RESOURCE_LOCAL transactions, so I can handle logging "manually". The second project uses JTA only since I only do logging operation there. Project A does CRUD operations, Project B does create operations only. Both projects run within the same Wildfly server. Is it possible that any problem, maybe with locking in database, transactions in Wildfly or whatever, could occur between project A and project B while accessing the same database with the same datasources from different projects as I do it?
I don't think so, but I'm afraid that some 'side effects' could occur I don't know yet.
There should not be any problem, as Datasource is managed by jboss, it will allocate connection as per your configuration, locking can occure if you are using same row for processing from different projects but let database take care of that.
And there are different entities involved for not creating any problem like tho TCP connection is same/ shared sessions and transactions are diffrent for operation, spring and hibernate both are mature and best what they do, unless you messed with configurations ;), your looks good.
I agree that in principal you should not worry! BUT, since we are not dealing with magic and there is always an explanation when something does not work, the only case you should worry is a potential business coupling between the 2 applications and of course ends up in the data base. What I am trying to say, is that if Application1 which uses the same DB with Application2, performs things on entities that eventually are expected to be visible/ update for the logic on the other application, then yes there might be a chance that you will face some technical deadlocks (eventually pretty fine for a DB) but could be a problem on the business code level.
It is a matter of design and higher coupling, which happens to result in a technical coupling on the DB. I am not sure if I describe it correct, as a high level concern :)

Infinispan - set per Entity expiration.lifespan

I have a java web application deployed on Jboss 6.1.0, that uses infinispan 5.2.6.Final.
I'm trying to set a per Entity specific expiration.lifespan following this guide
http://infinispan.org/docs/5.2.x/user_guide/user_guide.html#_advanced_configuration_2
for my Entity bean com.myenterprise.myproject.dal.ejb.entity.RefStatus.
The guide states the following:
You can also override eviction/expiration settings on a per entity/collection
type basis in such way that the overriden settings only afftect that particular
entity (i.e. com.acme.Person) or collection type (i.e. com.acme.Person.addresses).
For example:
<property name="hibernate.cache.infinispan.com.acme.Person.expiration.lifespan" value= "65000"/>
So, i've added the following element to my persistence.xml, to reduce the lifespan to 10 milliseconds for test purposes, in order to fine tune it later:
<property name="hibernate.cache.infinispan.com.myenterprise.myproject.dal.ejb.entity.RefStatus.expiration.lifespan" value= "10"/>
The setting produces no effects and the lifespan remains the default.
Do you know how I have to set the persistence.xml to successfully override the default expiration lifespan?
Setting the
<property name="hibernate.cache.infinispan.entity.expiration.lifespan" value= "10"/>
it works, but it affects all entity caches, and it is not what I want.
What follows is my application.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0">
<persistence-unit name="myProject_dal_PU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/datasources/myProject-DataSource</jta-data-source>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties>
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.bytecode.use_reflection_optimizer" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_minimal_puts" value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />
<property name="hibernate.cache.infinispan.com.myenterprise.myproject.dal.ejb.entity.RefStatus.expiration.lifespan" value= "10"/>
</properties>
</persistence-unit>
</persistence>
Thank you.
If you are running within the application server, apart from the entity name, you have to provide the deployment name and unit too. So, all such expiration properties need to be prepended with: hibernate.cache.infinispan.<warname>.<unitname>.<FQN of entity>...
In your case, I don't know the name of your deployment, but with the unit and FQN that you mention, something like:
hibernate.cache.infinispan.<warname>.myProject_dal_PU.com.myenterprise.myproject.dal.ejb.entity.RefStatus.expiration.lifespan
Spent hours to find correct configuration. Apparently it is as following:
Hibernate property should be in the following format:
hibernate.cache.infinispan.<prefix>.<full-class-name>.<property-name> where:
<prefix> - by default it is in the name that you see in a sort of JNDI name. In case of Wildfly, it is ear-name.ear/ejb-jar-name.jar#persistence-unit-name
However, it can be controlled by hibernate.cache.region_prefix property. Set region_prefix to "" and ignore the prefix.
<property-name> - String as it appears in org.hibernate.cache.infinispan.InfinispanRegionFactory class and in official Infinispan documentation.
In short, official Infinispan documentation is correct only when you set hibernate.cache.region_prefix to ""

Categories