Hibernate-search search from any indexed entity - jpa

I am using Hibernate-search for searching data in my Jboss application. I have 3 JPA entity classes that all extend BaseEntity class and each are indexed by Lucene. For example:
#MappedSuperclass
public abstract class BaseEntity implements Serializable {
#Temporal(TemporalType.TIMESTAMP)
private Date created;
public abstract Long getId();
}
#Entity
#Table(name = "DVD")
public class Dvd extends BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Field
private String title;
}
#Entity
#Table(name = "BOOK")
public class Book extends BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Field
private String author;
}
Now I would like to search for either DVD title or Book author by wildcard search query and get the result list as List. This is what I have this far:
public List<BaseEntity> search(String query, int firstResult, int maxResults) {
List<BaseEntity> results = null;
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
Query luceneQuery = new WildcardQuery(new Term("*", "*" + query + "*"));
FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, BaseEntity.class);
fullTextQuery.setFirstResult(firstResult);
fullTextQuery.setMaxResults(maxResults);
results = fullTextQuery.getResultList();
return results;
}
But with this I am not getting any results. How is it possible to get this to work or is there even way without using buildQueryBuilder for each entity? Thanks!

You'll want to use the varargs-style method for the classes, like so:
FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, DVD.class, Book.class);
This is because when Hibernate Search creates the search query, it adds the class name(s) to the query (for the _hibernate_class field, which is the indexed class' name).

Related

Spring JPA using primary key within #Embeddable class

In my application i have a scenario to fetch data from entity based on give input code and date.
The combination of code and date will be unique and will return a single record.
Below is my entity
class JpaEntity
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private id ;
private String code;
private Date date;
private title;
//Getters and Setters
}
I have tried below approcah by changing the entity.
class JpaEntity
{
private String title;
//Getters and setters
#EmbededId
private EntityId entityID
#Embedable
public static class EntityId implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private id ;
private String code;
private Date date;
//Getters and Setters
}
}
I am using the entity to search based on code and date
public interface PersistentDAO extends JpaRepository<JpaEntity,String> {
{
#Query("SELECT cal FROM JpaCalendar cal" + " WHERE cal.calendarId.currencyCode=:currencyCode "
+ " AND cal.calendarId.date=:date")
Optional<JpaCalendar> findById(String currencyCode, Date date);
JpaEntity findByID(String code,Date date)
}
But the JPA is throwing error saying Component Id is not found.
is it mandatory all the field in #Embedable are primary?
is it possible #Embedable class (composite id) contain the both primary and non-primay keys.
Since i am not supposed to change the structure of the table is there any way to achieve following:
Fetch record based on give code and date.
Insert new record where in id the primary key should be auto incremented
Please suggest.
Use #Embedded & #Embeddable and don't use static class inside class
class JpaEntity
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private id ;
#Embedded
private CodeDate codeDate;
private title;
}
#Embeddable
class CodeDate {
private String code;
private Date date;
}
You can use Jpa method naming query and create a CodeDate object call like this
public interface PersistentDAO extends JpaRepository<JpaEntity,String> {
{
JpaEntity findByCodeDate(CodeDate codeDate);
}

How to change table and column name in mongodb springboot application?

I am trying to change the name of collection and corresponding columns in mongodb-springboot application.
My entity class is:
#Entity
#Table(name = "user_profile")
public class UserProfile implements Serializable {
#Id
#Column(name = "user_profile_id")
private Long userProfileId;
#Column(name = "name")
private String name;
}
My Repository class is:
#RepositoryRestResource(collectionResourceRel = "user_profile")
public interface UserProfileRepository extends MongoRepository<UserProfile, Long> {
...
}
But the collection created is userProfile instead of user_profile. Also, there is an _id filed instead of user_profile_id in the collection.
What am I doing wrong?
use #Document in place of #Entity in case of MongoDB.
use #Document(collection = "User_detail") to name table.

Spring Data JPA order by value from OneToMany relation

I am trying to sort a result by nested collection element value. I have a very simple model:
#Entity
public class User {
#Id
#NotNull
#Column(name = "userid")
private Long id;
#OneToMany(mappedBy = "user")
private Collection<Setting> settings = new HashSet<>();
// getters and setters
}
#Entity
public class Setting {
#Id
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "userid")
private User user;
private String key;
private String value;
// getters and setters
}
public interface UserRepository extends JpaRepository<User, Long>, QuerydslPredicateExecutor<User> {
}
I want to have a result returned sorted by the value of one setting.
Is it possible to order by user.settings.value where settings.name = 'SampleName' using Spring Data JPA with QueryDSL?
I've used JpaSpecificationExecutor. let's see findAll for example.
Page<T> findAll(#Nullable Specification<T> spec, Pageable pageable);
Before call this method you can create your specification dynamically (where condition) and Pageable object with dynamic Sort information.
For example
...
Specification<T> whereSpecifications = Specification.where(yourWhereSpeficiation);
Sort sortByProperty = Sort.by(Sort.Order.asc("property"));
PageRequest orderedPageRequest = PageRequest.of(1, 100, sortByProperty);
userRepository.findAll(whereSpecifications, PageRequest.of(page, limit, orderedPageRequest));

Query for joins in Spring JPA

I have the below entities
#Entity
#Getter
#Setter
public class Aggregate {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#OneToMany(mappedBy = "aggregate")
private Set<Single> singleSet;
}
#Entity
#Getter
#Setter
public class Single {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private String id;
private Integer number;
#ManyToOne
#JoinColumn(name = "agg_id")
private Aggregate aggregate;
}
I also have the below repository
public interface AggregateRepo extends CrudRepository<Aggregate, Long> {
}
I want to return all associated Single records where number in object Single is equal to some random number
I am assuming that the query will be something like this
public interface AggregateRepo extends CrudRepository<Aggregate, Long> {
public List<Single> findBySingleSet_Number(Integer number);
}
However when I try to use Intellij to complete my named query it always populates like this
public interface AggregateRepo extends CrudRepository<Aggregate, Long> {
public List<Single> findBySingleSet_Empty_Number(Integer number);
}
I am wondering what the Empty stands for ?
Also should I create another Single repository since the query is related to returning Single records.

Query in Spring JPA using List of two parameters

public interface InventoryRepository extends JPARepository<Inventory, Long> {
List<Inventory> findByIdIn(List<Long> ids);
}
Above is working fine, however in same way I am trying to fetch the List or Map, based on multiple params List ids and List sortNumber.
I would be also happy with return type Map from the method.
I came up with below things, which isn't correct.
List<Inventory> findByIdANDSortNumberIn(List<Long> ids, List<Long> sortNumbers);
Should do it with help of Criteria ? Is there any better way to do it?
Entity :
#Entity
#Table(name = Constants.T_INVENTROTY)
#Data
public class Inventory implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = Constants.COLUMN_IN_DM)
private Long id;
#Column(name = Constants.COLUMN_PROD_DESCRIPTION)
private String prodDescription;
#Column(name = Constants.COLUMN_PROD_DESCRIPTION)
private Long sortNumber;
#Column(name = Constants.COLUMN_QUANTITY)
private long quantity
}
This should work
List<Inventory> findByIdInAndSortNumberIn(List<Long> ids, List<Long> sortNumbers);
You can specify And and do the same for multiple fields.