How to get Hibernate Search to index - hibernate-search

I have an app that I'm attempting to integrate hibernate search into. I'm using Hibernate Search 3.4.2. I have a domain class that looks like the following:
#Indexed
public Group {
#Fieldindex (index = Index.TOKENIZED, store = Store.YES)
private String groupName;
}
In my test cases, I create a few Groups and save them to the database. Once stored in the database, I create the index and then search for given text strings. This seems to work.
The problem I'm having is that any new Groups created after the index has been created are not indexed. From what I've read, I thought that once the index is created, any new items persisted would be automatically indexed with the new values, but this doesn't seem to be the behavior I'm getting. Is there something I've missed in the way of configuration? Or do I have to do something manually to tell Hibernate Search that I've added a new object to be indexed?
Needless to say, I'm a bit confused...
[EDIT] I'm using JPA, so my hibernate search confguration is contained in my persistence.xml as follows:
<property name="hibernate.search.default.directory_provider" value="filesystem"/>
<property name="hibernate.search.default.indexBase" value="D:\var2\lucene\indexes"/>
I can see that the index files are created, and I can use Luke to view the contents, they just don't ever seem to get updated when I persist a new object.

As stated in the documentation "By default, every time an object is inserted, updated or deleted through Hibernate, Hibernate Search updates the according Lucene index".
What I would do is to check my persistence.xml and see if I have not accidentally set hibernate.search.indexing_strategy = manual
If that's not the case, maybe you could try to force it and see if that works?
hibernate.search.indexing_strategy = event
Which framework are you using? Maybe check out the last post of this question.
// Jakob

Related

mongodb save of embedded document succeeds; however next read does not have the changes. Why?

Update
Ockham's razor sliced through this problem.
Turns out the issue was:
Document did not have an _id field
#Id
private String id;
So the update() method would insert a new record rather than update existing record.
the 'find' code used 'findOne()'
for some reason findOne() appeared to behave differently in different environemts (i.e. in local dev environments it would retrieve 'most recent', but on our server environment , retrieved the 'oldest'.). Whatever something in local env masked the problem.
TLDR
'save and immediate retrieve' mongodb document with embedded document (i.e. field w/ java object/json) does not show expected updates
problem appears intermittently and only on some environments
Background
I'm new to mongo so don't know the tricks/techniques/gotchas/etc.. I'm versed in relationaldb and transactions, so this error threw me.
for better or worse, I designed a mongo collection that looks like this:
#Document
public class BidOffers {
...
// note 'Suppliers' here is plural, ie. offers from multiple suppliers
SuppliersOffers offers;
where SuppliersOffers object simply has a list of SupplierOffer objects
public class SuppliersOffers {
List<SupplierOffer> offers = new ArrayList<>();
and SupplierOffer just has a 'supplier code' and a price
public class SupplierOffer {
String supplierCode
BigDecimal price
}
Usecase
In this usecase:
Retrieve document BidOffers from mongodb
Note that document has only one offer
Add a new offer to the list
Save document
Print saved document to log, i.e. and note/confirm "saved document now has two offers in list, not just one"
Some (short) time later (i.e. in the same thread) retrieve the document
Expected Results
retrieved document has two offers
Actual Result
retrieve document has only one offer
More details
Java 8
Spring Boot 2.x
Problem appears on Mongodb 4.0 version (AWS Managed Service)
Problem appears regularly, but not 100% consistently
I do not see this problem when testing locally (Mongdb 3.6.8)

Hibernate persisting incorrect values

I have some Hibernate code running against a Postgres 9.5 DB, which looks like roughly like below (anonymized) -
Integer myEntityId = myEntity.getId();
getCurrentSession().evict(myEntity);
myEntity.setId(null);
MyEntity clonedMyEntity = (MyEntity)getCurrentSession().merge(myEntity);
myEntity.setMyBooleanField(false);
getCurrentSession().save(myEntity);
I have an entity myEntity with a large number of fields. I want to create a duplicate of the record with only 1 field value changed. To achieve this, I evict the entity from session, set Primary Key to null, merge it back to session, set the field I want to change, and then save the entity to DB. However, this code (which was working correctly for some time), is not working now. It sees incorrect value for the boolean field I am trying to modify - as a result violating some database constraints. Please help me fix this or suggest a better way to achieve what I am trying.
The error was happening not on adding this record but on add of another record to an audit table, triggered by the addition of this record. A coworker suggested me to use Eclipse Breakpoint view and use the add breakpoint option there and select the ConstraintViolationException class - this helped me to see the error for which trigger was failing and why and accordingly modify the data to suit the database constraint.

How to Query a Read-Only Field with ORMLite

I am trying ORMLite as an ORM for a project I am developing. I am mapping a java class to a table that has some auditing fields (ie. updatedby, updatedtime, etc.). The auditing fields are maintained by the database using triggers to ensure that no matter what front-end the user is using these fields will always be correctly updated when a record is updated.
I need to include these fields in my client application to inform the user when the record was last updated, but the user can't change them. Is there a way to annotate the class so that ORMLite won't try to perform updates on these fields or include them in insert statements. The database will deny an update if these fields are included in an update statement (which is why I can't just write back the original value that was queried from the database).
I tried using the #DatabaseField(persisted = false) annotation on the Java fields, but then they don't get queried at all so the Java object is never populated with these fields.
Basically, I need these fields to be included in SELECT statements, but not included in INSERT or UPDATE statements (equivalent to a #DatabaseField(immutable = true) annotation).
Interesting pattern. ORMLite didn't support the feature at the time but now it does as of version 4.46.
There is now a #DatabaseField(readOnly=true) annotation field.

JPA EclipseLink table creation order

I have a working project that uses JPA to persist data on MySQL (EclipseLink as provider). Recently I wanted to drop the database and create it again with the tables via Eclipse => EclipseLink 'Generate tables from entities'. I also have the persistence.xml updated (first generated automatically, then modified manually to narrow down on this problem).
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>xxx.entity.options.Difficulty</class>
<class>xxx.entity.options.Options</class>
(Omitted the rest since it is ok otherwise => it is working in general)
The problem is that when I generate the tables I get the error:
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'xxx.DIFFICULTY' doesn't exist
Error Code: 1146
(The entity classes have table names defined:
#Entity
#Table(name = "DIFFICULTY"))
If I comment out the 'Options' from persistence.xml, the 'DIFFICULTY' table gets created ok. Then uncommenting 'Options' again and re-generating the tables => the 'OPTIONS' table will be created also (Options has #ManyToOne association with the Difficulty).
In the persistence.xml I have
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
as I am still developing.
In the Options class I have
#ManyToOne(optional = false, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
private Difficulty difficulty = null;
(Many Options are suppose to have the same Difficulty selected, so none really owns one. I hope this is correct?)
After The Difficulty and Options tables were created successfully, I was able to re-create the rest of the database tables.
The question is that should I (be able to) specify the order in which the tables are created?
Have I something wrong with the #ManyToOne association?
Already spent couple of hours on this issue, but couldn't figure it out what is the problem.
Sorry for the long text, I just try to explain the whole situation.
Last time I received 'tl; dr;' answer (didn't know by that time what it meant), I spent 6 hours looking the wrong thing, so please do not bother to answer in such case.
If you look at the exceptions stack, you'll see it is coming from your entity's default constructor. This constructor is trying to issue a query by obtaining an entitymanager, and is failing because the table it needs doesn't exist yet. When you create that one table, the constructor can query it, which allows everything to proceed.
You should not have business logic in your default constructor. This is used by the provider, and is getting called during deployment before DDL. Removing that will resolve the issue.
Are you changing the class/schema in between your last create? It could be that you have added or removed new relationships, so EclipseLink is not able to drop the old constraints.
For drop-and-create-tables EclipseLink will basically do the following,
drop known constraints
drop known tables
create known tables
create known constraints
In the latest release EclipseLink will try a couple drop passes to try and handle unknown constraints, but the best method for a rapidly changing development schema would be to drop the entire schema in between deployments.

possible to return only one column using JPA

I have an Open JPA entity and it successfully connects a many-to-many relationship. Right now I successfully get the entire table, but I really only want the ID's from that tables. I plan on calling the database later to reconstruct the entities that I need (according to the flow of my program).
I need only the ID's (or one column from that table).
1) Should I try and restrict this in my entity beans, or in the stateless session beans that I will be using to call the entity beans
2) If I try and do this using JPA, how can I specify that I only get back the ID's from the table, instead of the whole table? So far looking online, I don't see a way that you can do this. So I am guessing there is no way to do this.
3) If I simply just manipulate the return values, should I create a separate class that I will be returning to the user that will return only the required id list to the user?
I could be completely wrong here, but from the looks of it, I don't think there is a simple way to do this using JPA and I will have to return a custom object instead of the entity bean to the user (this custom object would only hold the id's as opposed to the whole table as it currently does)
Any thoughts... I don't think this is really relevant, but people are always asking for code, so here you go...
#ManyToMany(fetch=FetchType.EAGER)
#JoinTable(name="QUICK_LAUNCH_DISTLIST",
joinColumns=#JoinColumn(name="QUICK_LAUNCH_ID"),
inverseJoinColumns=#JoinColumn(name="LIST_ID"))
private List<DistributionList> distributionlistList;
Currently how I get the entire collection of records. Remember I only want the id...
try
{
//int daSize = 0;
//System.out.println("Testing 1.2..3...! ");
qlList = emf.createNamedQuery("getQuickLaunch").getResultList();
}
This is how I call the Entity beans. I am thinking this is where I will have to programatically go through and create a custom object similar to the entity bean (but it just has the ID's and not the whole table, and attempt to put the id's in there somewhere.
What are your thoughts?
Thanks
I believe I just figured out the best solution to this problem.
This link would be the answer:
my other stack overflow answer post
But for the sake of those too lazy to click on the link I essentially used the #ElementCollection attribute...
#ElementCollection(fetch=FetchType.EAGER)
#CollectionTable(name="QUICK_LAUNCH_DISTLIST",joinColumns=#JoinColumn(name="QUICK_LAUNCH_ID"))
#Column(name="LIST_ID")
private List<Long> distListIDs;
That did it.
Sounds like you want something like this in your quickLaunch class:
#Transient
public List<Integer> getDistributionListIds () {
List<Integer> distributionListIds = new LinkedList<Integer>();
List<DistributionList> distributionlistList = getDistributionlistList();
if (distributionlistList != null) {
for (DistributionList distributionList : distributionlistList)
distributionListIds.add(distributionList.getId());
}
return distributionListIds;
}
I had to guess a little at the names of your getters/setters and the type of DistributionList's ID. But basically, JPA is already nicely handling all of the relationships for you, so just take the values you want from the related objects.