Does Hibernate Search load entity associations and can I mix free text queries with native SQL? - hibernate-search

package example;
...
#Entity
#Indexed
public class Book {
#Id
#GeneratedValue
private Integer id;
#Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
private String title;
#Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
private String subtitle;
#Field(index = Index.YES, analyze=Analyze.NO, store = Store.YES)
#DateBridge(resolution = Resolution.DAY)
private Date publicationDate;
#IndexedEmbedded
#ManyToMany
private Set<Author> authors = new HashSet<Author>();
#OneToMany(mappedBy="book")
List<BookPages> bookPages;
}
1) If the search result is of type Book.class does the result contain #ManyToOne objects (bookPages) or do I have to load them separately? Because I need them for showing the result.
2) Is it possible to add a native sql clause to the search? Because I need to limit the result and for that I have to JOIN another table which is not declared in Book.class.

That is a basic Hibernate ORM question, not related to Hibernate Search. Yes you can always navigate from one entity to its relations by just invoking the getter / accessing the fields: depending on your (configurable) fetch strategy it will either have the relation preloaded in "one shot" when loading the main entity (likely with a JOIN) or fetch it transparently on demand. This configuration is however not have any effect on functionality, more a performance tuning option.
No you can't mix SQL with an Hibernate Search (Fulltext) query; what you can do is to expose the needed data from the other table in the mapping - which would be a cleaner mapping anyway - and then use the Hibernate Search annotations to make sure all fields you need are indexed as well, so that you can include the restrictions in the FullTextQuery directly; fill perform much faster as well than any SQL.

It is not possible to mix native SQL with hibernate search query, as there is no way to intersect the results from both queries without iterating on at least one of the results.
See the documentation reference about this exact question.
Hibernate Search - FAQ - Can I mix HQL and Lucene queries?
http://hibernate.org/search/faq/

Related

Spring data jpa querydsl projection with joins

I'd like to optimize a queryDSL + Spring data query. Currently I am using a BooleanBuilder as the predicate, which would be fine, but it joins too many tables. I don't need all the columns from the tables and I don't need some of the tables at all. I believe using a projection would reduce the number of tables joined.
I tried with using a Projections.bean() and also with extending MappingProjection, but both approaches result in not using joins but selecting from multiple tables which results in less rows than what's needed.
My data structure consists of a Booking entity and some related entites like User, so looks something like the following:
#Entity
public class Booking {
#ManyToOne
#JoinColumn(name = "userId", nullable = false)
private User endUser;
}
#Entity
public class User {
#OneToMany(cascade = CascadeType.ALL, mappedBy = "endUser", fetch = FetchType.LAZY)
private List<Booking> bookings;
}
I implemented a custom queryDSL projection repository as described here: Spring Data JPA and Querydsl to fetch subset of columns using bean/constructor projection
I'm trying a projection like the following:
Projections.bean(Booking.class,
booking.uuid,
Projections.bean(User.class,
booking.endUser.uuid
).as(booking.endUser.getMetadata().getName()
);
The sql generated by the current solution looks something like this:
select (...)
from booking booking0_,
user user12_
where booking0_.user_id=user12_.id
So, how can I make QueryDSL join the tables instead of selecting from all of them?
Am I on the right path to try to optimize the query? Does the projection make sense?
I ended up creating a DB view, making an Entity for it and then querying that with querydsl. This is really simple, straightforward and the performance is good too.
This is probably where ORMs are just not capable enough.

Will my Spring Data Jpa method return all foreign fields?

If I have a table like this :
Client
private Long int;
private String name;
#ManyToOne(mappedBy="otherField")
private Address addresses;
And I Create a repository that extends JPA Repository. Given the name of the client, I want to get as results also the Address Table fields.
Using the method
Client findByName(String name)
Will my this also return all the fields that are on the Address Table ?
Like:
Address
private Long id;
private String city;
private Int code;
private String street;
From the docs
The Hibernate recommendation is to statically mark all associations
lazy and to use dynamic fetching strategies for eagerness. This is
unfortunately at odds with the JPA specification which defines that
all one-to-one and many-to-one associations should be eagerly fetched
by default. Hibernate, as a JPA provider, honors that default.
So Hibernate behaves the same as JPA:
OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER
Also take a look at the JPA sepcifications here.

How to retrieve nested data in JPQL?

working with OpenJPA2 persistence. I have a very simple entity class, that does have a String property and a List property. I do persist its instances flawlessly with the nested List (in a JSF2 web project). I check the database and there appears two tables (I use automatic schema generation), one for the entity itself, and other table for the nested List. All data persisted using EntityManager is stored fine on both tables.
Problem is I cannot retrieve nested data. I mean, I do a Query for getting all instances of the entity, but the List of all instances come empty.
(DB Engine is MySQL. ORM is OpenJPA2. Server is TomEE 1.6. IDE is Netbeans 8. I use automatic schema generation, so I DO NOT WANT to design the database tables, and I DO WANT to let the ORM create the tables, so I can work purely with objects and forget about DB.)
following is Entity Class code:
#Entity
public class Cliente implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String nombre;
#ElementCollection
private List<String> emails = new ArrayList<String>();
// getters and setters omitted for brevity.
It does have an associated Facade Class, which is ClienteFacade. It includes the getAll method which uses a JPQL Query.
public List<Cliente> listaClientes(){
Query query = em.createQuery("SELECT c FROM Cliente c");
return query.getResultList(); }
Problem is, I get all instances of the entity in a List, but all lists of List emails come out empty. I think problem may be in the JPQL query. Still trying to learn JPQL with some difficulty... so please, How can I retrieve the nested data with JPQL?
Many thanks!
Try #ElementCollection(fetch = FetchType.EAGER) because the default type is lazy. That means that the lists are not loaded directly.

What is the best practice for joins in MongoDB?

I have two class called School and Student as you see. I want to search for "students that school names are bla bla bla" and "schools that have students which has higher grade than 90". I read some documents but I am a little confused.
public class School extends BasicDBObject {
private int id;
private String name;
private String number;
private List<Student> studentList = new ArrayList<Student>();,
//getter and setters
}
public class Student extends BasicDBObject{
private int id;
private String name;
private String grade;
private School school;
//getter and setters
}
MongoDB is not a relational database. It doesn't support joins. To simulate a join, you have to query the first collection, get the results, and then query the second collection with a large $in query filled with the applicable key values of the documents returned by the first query. This is as slow and ugly as it sounds, so the database schema should be designed to avoid it.
For your example, I would add the school names to the Student documents. This would allow to satisfy both of your use-cases with a single query.
Anyone coming from a relational database background would now say "But that's a redundancy! You've violated the second normal form!". That's true, but normalization is a design pattern specific to relational databases. It doesn't necessarily apply to document-oriented databases. So what design patterns are applicable for document-oriented databases? Tough call. It's a new technology. We are still figuring this out.

How to sort a JSF 2 dataTable in two ways, by two variable/columns?

I have the following Entity:
#Entity
public class Question {
#Id
#GeneratedValue
private Integer id;
private String content;
private boolean visible;
private Date displayDate;
}
Only one Question can be visible in the database all the time. The requirement for the list in the dataTable is that the first line must be the visible Question and the others must be ordered by displayDate. Any idea?
Sorting is usually performed in DB (model) side, not in JSF (view) side. Your SQL (and equivalently also JPQL) query should be written that way that it returns exactly the rows you need, without any necessary postprocessing (the DB is namely endless much more efficient in the selecting job than Java/JSF).
In plain SQL terms, that would be
(...) ORDER BY visible DESC, displayDate ASC
If you're using JPA, you should surely be able to extract the proper JPQL syntax for that
(...) FROM Question q (...) ORDER BY q.visible DESC, q.displayDate ASC