Is #NamedQuery necessary when mapping entity to a view? - jpa

From many examples online, I saw people add #NamedQuery before their entity class, I removed the annotation and it still works, so I am curious if it's necessary to always add this annotation to entities? BTW, I am using Spring data as the JPA vendor.
What's the best practice here and why?
#Entity
#NamedQuery(name = "User.findByEmailAddress",
query = "select u from User u where u.emailAddress = ?1")
public class User {
//Do stuff
}

No, named queries are not needed. They allow you to predefine queries and then use them at runtime rather than dynamically creating each query. This is described in the docs here

Related

Is it possible to move named queries of an entity to another class

I have an entity named Client, And it has some named queries and native named queries. What I want to do is, I want to move this named queries to another class. For that I would like to extend the Client entity by another class ClientQuery. And move all named,native queries to that class. Is it possible to do so?
Client CLASS
#XmlRootElement(name = "CLIENT_DETAILS")
#XmlAccessorType(XmlAccessType.FIELD)
#Entity
#NamedQueries({
#NamedQuery(name = Client.GET_CLIENT_BYLANGID,
query = "select T from Client T where T.clientPK.langId=:langId")
})
public class Client implements Serializable {
public static final String GET_CLIENT_BYLANGID = "Client.getClientByLangId";
As I understand, you want to know whether it correct to move the #NamedQuery out of the Entityclass to a non-entity class.
I have quickly checked the specification and did not see any restrictions about that. Additionally I have tried to put in an mapping.xml an <named-query> element outside of the <entity> element and it is xml-valid, so it is legal.
If you move the #NamedQuery in a class that is not an entity that won´t work as hibernate only scan the classes that are entities. You will find something like NamedQuery not found, also it is a good practice to have them in the entity that has more reference to them.

A select JPA query that ignores the related entities of one-to-many relation, is that possible?

I am new in JPA, so excuse me if my question seems basic.
I have an entity called User, which is related to a list of other entities like follow:
#OneToMany(cascade = CascadeType.ALL , mappedBy = "user")
private List<session> sessionList;
In a controller class, I defined a find method in a RESTFull manner like follow:
#GET
#Path("/Users")
#Produces("application/json")
public List<UserDevice> findAllUsers()
{
return em.createQuery("SELECT u FROM User u").getResultList();
}
The returned result contains all the sessions of the users which is normal, but make the result huge though I just want to retrieve the basic information of the users (all the simple columns).
My question is: is it possible to ignore the related entities and just keep the columns of the actual entity? Thank you very much
Unless you explicitely map the association as eagerly loaded (using #OneToMany(fetch = FetchType.EAGER)), the above query should only return the fields of the users, and should not load their sessionList.
If the sessions are loaded, then the association is marked as eagerly loaded, or you load them lazily by calling a method of the List<Session>.

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.

CriteriaBuilder and using alias for select cause

I would like to create a query with CriteriaBuilder for this kind of sql;
SELECT myDefinedAlias.id, myDefinedAlias.name, myDefinedAlias.aFieldForFK select from Person as myDefinedAlias where myDefinedAlias.name = ?1
How can i accomplish defining an alias for this?
I can create queries without aliases but i cannot define aliases...
CriteriaQuery<Person> cq = criteriBuilder.createQuery(Person.class);
Root<Person> person = cq.from(Person.class);
cq = cq.select(person);
cq = cq.where(criteriaBuilder.equal(person.get(Person_.name), "Chivas")))
I need this for QueryHints, batch fetch.
.setHint(QueryHints.BATCH, "myDefinedAlias.aFieldForFK.itsNestedAttribute");
I am stuck and couldn't find anything regarding my problem. Anyone?
Regards
Doing cq.select(person).alias("myDefinedAlias") assigns your alias which can subsequently be used in batch/fetch query hints. Eclipselink supports nested fetch joins as long as you do not transfer to-Many relations (collections).
I.e..setHint(QueryHints.BATCH, myDefinedAlias.toOneRelation.toManyRelation") works while .setHint(QueryHints.BATCH, .setHint(QueryHints.BATCH, "myDefinedAlias.toManyRelation.toOneRelation") shouldn't.
I think you are going about this the wrong way. JPA needs the sql-statement-aliases for itself to use when generating sql-statements.
For the nested query hints to work, the relationship needs to be specified in the entities.
For example, if your Person entity have a OneToMany mapping to a House entity - and the property name in the Person class is livedInHouses. The query hint would become:
.setHint(QueryHints.BATCH, "Person.livedInHouses"). Its damn near impossible to use FKs that exists in the database but are not annotated as relations on/in entities in JPA.

Using Annotations In JPA can I limit child records with a where clause?

I have an EJB with an #onetomany relationship like this in my parent class (Timeslot):
#OneToMany(mappedBy = "rsTimeslots")
private List<RsEvents> rsEventsList;
I also have a function to get the rsEventList:
public void setRsEventsList(List<RsEvents> rsEventsList) {
this.rsEventsList = rsEventsList;
}
This was all auto generated so far. In my view-layer code I can get a timeslot object and do something like timeslot.getRsEventList() and get all children of this timeslot. Now I need to restrict that list based on a criteria. For example I only want events that are children of this timeslot with a status of 1. Is there a way to do this with annotations?
Not in JPA.
Normally you would execute a Query for this, using JPQL or the criteria API.
Some JPA providers do provide ways to restrict relationships, but I think you would be best off with a query, or providing a get/filter method on your class that just accesses the list and filters it (i.e. getStatus1Events()).
For an EclipseLink example of having a criteria on a mapping see,
http://wiki.eclipse.org/EclipseLink/Examples/JPA/MappingSelectionCriteria