Query in Spring JPA using List of two parameters - spring-data-jpa

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.

Related

JEE, JPA facade edit many to many relation

I'm facing an issue i can't figure out.
I got 2 entities : User and Course with a Many to Many relationship
User.java
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
#ManyToMany(cascade = CascadeType.MERGE)
#JoinTable(
name="USR_COURSES",
joinColumns=#JoinColumn(name="USR_ID", referencedColumnName="ID"),
inverseJoinColumns=#JoinColumn(name="COURSE_ID",referencedColumnName="ID"))
private List<Course> courses;
...
Course.java
#Entity
#Table(uniqueConstraints=#UniqueConstraint(columnNames="CODE"))
public class Course implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String code;
private String name;
private String content;
#ManyToMany(mappedBy="courses",cascade = CascadeType.MERGE)
private List<User> users;
...
If i create a user and set him some courses, the join table will be updated with the new relations between the User and the Courses.
However if i want to edit a user by adding him courses, the join table is not update :
List<Course> test = myUser.getCourse();
test.add(facade.find(1l));
myUser.setCourse(test);
userFacade.edit(myUser);
I'm using NetBean and the AbstractFacade generated.
Thanks for helping !
In order for the cascade to work in that case you would need to set dependencies in the both sides of the ManyToMany relationship.
That means that you would need to do the following:
List<Course> test = myUser.getCourse();
Course course = facade.find(1l);
course.getUsers().add(myUser);
test.add(course);
myUser.setCourse(test);
userFacade.edit(myUser);
When you query for the Course you do not get the user list because you only have Cascade.MERGE set up on that relationship. This means that you need to set it manually as above.

The attribute [] is not present in the managed type

I'm doing an application that has this relation ship: A personal contact has an Email.
So i'm trying to find the Emails from the personal contact and I'm doing this query using Criteria but always return IllegalArgumentException:
#Override
public Email findByEmail(PersonalContact personalContact) {
CriteriaBuilder criteriaBuilder = entityManager().getCriteriaBuilder();
CriteriaQuery<Email> criteriaQuery = criteriaBuilder.createQuery(Email.class);
Root<Email> email = criteriaQuery.from(Email.class);
criteriaQuery.where(criteriaBuilder.equal(
email.get("personalContact"), criteriaBuilder.parameter(PersonalContact.class, "personalContact")));
TypedQuery<Email> typedQuery = entityManager().createQuery(criteriaQuery);
typedQuery.setParameter("personalContact", personalContact);
return typedQuery.getSingleResult();
}
Personal contact is like a foreign key.
And here is my Email class:
#Entity
#Table(name = "Email")
public class Email implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String mainEmail;
private List<String> secondaryMail;
#JoinColumn(name = "personal")
#OneToOne(fetch = FetchType.LAZY)
private PersonalContact pContact;
and here is my Personal Contact class:
#Entity
#Table(name = "PERSONALCONTACT")
public class PersonalContact extends Contact implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "PERSONAL_ID")
private Long id;
//Other variables
#OneToOne(fetch=FetchType.LAZY, mappedBy="personal")
private Email email;
And every time I execute the query this is the return:
Exception in thread "AWT-EventQueue-0"
java.lang.IllegalArgumentException: The attribute [personalContact] is
not present in the managed type [EntityTypeImpl#1230307250:Email [
javaType: class csheets.ext.crm.contact.Email descriptor:
RelationalDescriptor(csheets.ext.crm.contact.Email -->
[DatabaseTable(Email)]), mappings: 5]].
I did some search and the others programmers said the problem was on the name of the variables... but i guess the names of the variables are correct.
So what I'm doing wrong? perhaps the relationship between that two classes?
Thank you!
If you read the exception message carefully, you'll find that it is complaining that class Email does not have a property (attribute) called personalContact, and indeed, there is no such property. Presumably you meant the pContact property?
(Mistakes such as this are why I recommend querying JPA via Querydsl: code completion would likely have prevented this mistake, and even if not, you would have gotten a clear compiler message when trying to use a non-existing property)

Hibernate-search search from any indexed entity

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).

EJB JPA QL. Need query to get data from DB by element in Collection object

I am facing a proble that put me in difficult situation.
I have class Article:
#Entity
#Table(name = "Articles")
public class Article implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="article_id")
private Long id;
#Column(name="a_name")
private String name;
#Column(name="a_content")
private String content;
#OneToMany
#Column(name="a_tag")
private Collection <Tags> tag;
#Entity
#Table(name = "Tags")
public class Tags implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="tag_id")
private Long tag_id;
#Column(name="tag_name",nullable=false)
private String tag_name;
#Column(name="tag_descr")
private String tag_descr;
//position 0 - supertag
//position 1 - subsupertag
//position 2 - subtags
//Collection limited to 3 elements.(3 tags at most, necessaryly Super,subsuper,subtag
#Column(name="super_tags")
#OneToMany
private Collection<Tags> supertags = new ArrayList<Tags>(3);
//0-supertag 1-subsupertag 2- subtags
#Column(name="tag_type")
private int tag_type;
My tagging system is such that I have Supertag, subsuprttag and subtag. Supertag is parent for subsupertag and subtag, subsupertag is parent for subtag.
Each article has super, subsuper and sub tags.
Now, I want to get only articles from database, that has a certain tag, but have no idea how to refere to , for example, element 2 in Collection tags (by name or position), (which would be subtag).
final String q = "SELECT f FROM Article f WHERE f.a_tag= ..I m lost here ...
EntityManager em;
em.createQuery(q).getResultList();
I hope my question is clear enough. I gave it my best shot)) Thank you.
You can join to the tags to access them in JPQL,
see,
http://en.wikibooks.org/wiki/Java_Persistence/JPQL#JOIN
As for the type of Tag, how is the type stored in the database?

JPA Many to One relationship

I am bit beginner on JPA and need some help on fetching the Many to One relationship in JPA.
I have below entities.
User which stores all user information . User extends Audiatable abstract class which is for holding auidt paramters like last modified date, creation date etc.
I am trying to add another fields as lastUpdatedByUser which should get fetched from lastUpdatedBy for which I amtrying to add Many-One relationship.
But the relation is not working somehow, am I doing something wrong here?
AuditableEntity.java
public abstract class AuditableEntity<T extends Entity<T, ID>, ID> implements Auditable {
private static final long serialVersionUID = 1L;
#Column(name = "cruserid")
private Long createdBy;
#Column(name = "crdate")
#Type(type = JpaConstants.TYPE_LOCAL_DATE_TIME)
private LocalDateTime createdOn;
#Column(name = "chuserid")
private Long lastUpdatedBy;
#Column(name = "chdate")
#Type(type = JpaConstants.TYPE_LOCAL_DATE_TIME)
private LocalDateTime lastUpdatedOn;
#Transient
#ManyToOne(fetch = FetchType.LAZY, targetEntity = User.class)
#JoinColumn(name = "usrId", referencedColumnName = "chuserid")
private User lastUpdatedByUser;
User.java
public class User extends AuditableEntity<User, Long> {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "usrId")
private Long id;
#Column(name = "usrName")
private String name;
#Column(name = "loginame")
private String loginName;
}
Well, you marked the association with #Transient, which means that the field is not persistent and should be ignored by JPA.
And you also seem to have two different fields to store the same information: lastUpdatedBy and lastUpdateByUser. Remove the first one, and map the second one as
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "chuserid")
private User lastUpdatedByUser;
This tells that the association is a ManyToOne to the User entity (no need to specify the targetEntity since it's the type of the field), and that this association is materialized by the join column named "chuserid", in the auditable entity's table, and referencing the ID of the User entity (referencedColumnName is only useful when you use composite IDs, or when you reference an entity by a column which is the the ID)