Hibernate setParamater a class - java

I am new to Hibernate.
I want to create a public Object getById(Class class,long id) function. I tried creating query like: from :nameEntity where id= :id but I'm facing problems when setting parameter for nameEntity. Hibernate doesn't recognize it as a parameter.
I used session.createQuery function. Could you please help me?

You will either have to do String concatenation to achieve this:
session.createQuery("from " + clazz.getName() " where id=:id").
setParameter("id", id).
uniqueResult();
or use the Criteria API:
session.createCriteria(clazz).
add(Expression.eq("id", id).
uniqueResult()

I want to create a public Object getById(Class class, long id) function. I tried creating query like:" from :nameEntity where id=:id " but I'm facing problems when setting parameter for 'nameEntity'. Hibernate doesn't recognize it as a parameter.
Don't build a query, use the load() or get() methods from the Session. They are actually heavily overloaded, allowing to pass the class either as Class or String, the persistent object identifier and, if required, a lock option (for pessimistic locking):
get(Class clazz, Serializable id)
load(Class theClass, Serializable id)
get(Class clazz, Serializable id, LockOptions lockOptions)
load(Class theClass, Serializable id, LockOptions lockOptions)
get(String entityName, Serializable id)
load(String entityName, Serializable id)
get(String entityName, Serializable id, LockOptions lockOptions)
load(String entityName, Serializable id, LockOptions lockOptions)
What are the differences between get() and load()? This is explained in the Reference Documentation:
10.3. Loading an object
The load() methods of Session
provide a way of retrieving a
persistent instance if you know its
identifier. load() takes a class
object and loads the state into a
newly instantiated instance of that
class in a persistent state.
Cat fritz = (Cat) sess.load(Cat.class, generatedId);
// you need to wrap primitive identifiers
long id = 1234;
DomesticCat pk = (DomesticCat) sess.load( DomesticCat.class, new Long(id) );
Alternatively, you can load state into
a given instance:
Cat cat = new DomesticCat();
// load pk's state into cat
sess.load( cat, new Long(pkId) );
Set kittens = cat.getKittens();
Be aware that load() will throw an
unrecoverable exception if there is no
matching database row. If the class is
mapped with a proxy, load() just
returns an uninitialized proxy and
does not actually hit the database
until you invoke a method of the
proxy. This is useful if you wish to
create an association to an object
without actually loading it from the
database. It also allows multiple
instances to be loaded as a batch if
batch-size is defined for the class
mapping.
If you are not certain that a matching
row exists, you should use the get()
method which hits the database
immediately and returns null if
there is no matching row.
Cat cat = (Cat) sess.get(Cat.class, id);
if (cat==null) {
cat = new Cat();
sess.save(cat, id);
}
return cat;
You can even load an object using an
SQL SELECT ... FOR UPDATE, using a
LockMode. See the API documentation
for more information.
Cat cat = (Cat) sess.get(Cat.class, id, LockMode.UPGRADE);
Any associated instances or contained
collections will not be selected FOR
UPDATE, unless you decide to specify
lock or all as a cascade style for the
association.
It is possible to re-load an object
and all its collections at any time,
using the refresh() method. This is
useful when database triggers are used
to initialize some of the properties
of the object.
sess.save(cat);
sess.flush(); //force the SQL INSERT
sess.refresh(cat); //re-read the state (after the trigger executes)
How much does Hibernate load from the
database and how many SQL SELECTs will
it use? This depends on the fetching
strategy. This is explained in Section
20.1, “Fetching strategies”.
How to choose between them?
Choosing between get() and
load() is easy: If you’re certain the
persistent object exists, and
nonexistence would be considered
exceptional, load() is a good option.
If you aren’t certain there is a
persistent instance with the given
identifier, use get() and test the
return value to see if it’s null.
See also
Hibernate Load and Get
Loading Entities with Hibernate
Advantage of load() vs get()
Related question
Hibernate: Difference between session.get and session.load

Related

JPA Query with several different #Id columns

Problem
To make my code cleaner i want to introduce a generic Repository that each Repository could extend and therefore reduce the code i have to have in each of them. The problem is, that the Ids differ from Class to Class. On one (see example below) it would be id and in the other randomNumber and on the other may even be an #EmbeddedId. I want to have a derived (or non derived) query in the respository that gets One by id.
Preferred solution
I Imagine having something like:
public interface IUniversalRepository<T, K>{
#Query("select t from # {#entityName} where #id = ?1")
public T findById(K id);
}
Ecample Code
(that does not work because attribute id cannot be found on Settings)
public interface IUniversalRepository<T, K>{
//should return the object with the id, reagardless of the column name
public T findById(K id);
}
// two example classes with different #Id fields
public class TaxRate {
#Id
#Column()
private Integer id;
...
}
public class Settings{
#Id
#Column() //cannot rename this column because it has to be named exactly as it is for backup reason
private String randomNumber;
...
}
// the Repository would be used like this
public interface TaxRateRepository extends IUniversalRepository<TaxRate, Integer> {
}
public interface SettingsRepository extends IUniversalRepository<TaxRate, String> {
}
Happy for suggestions.
The idea of retrieving JPA entities via "id query" is not so good as you might think, the main problem is that is much slower, especially when you are hitting the same entity within transaction multiple times: if flush mode is set to AUTO (with is actually the reasonable default) Hibernate needs to perform dirty checking and flush changes into database before executing JPQL query, moreover, Hibernate doesn't guarantee that entities, retrieved via "id query" are not actually stale - if entity was already present in persistence context Hibernate basically ignores DB data.
The best way to retrieve entities by id is to call EntityManager#find(java.lang.Class<T>, java.lang.Object) method, which in turn backs up CrudRepository#findById method, so, yours findByIdAndType(K id, String type) should actually look like:
default Optional<T> findByIdAndType(K id, String type) {
return findById(id)
.filter(e -> Objects.equals(e.getType(), type));
}
However, the desire to place some kind of id placeholder in JQPL query is not so bad - one of it's applications could be preserving order stability in queries with pagination. I would suggest you to file corresponding CR to spring-data project.

Spring data JPA getById vs GetReferenceById

Does anyone know why getById and GetReferenceById work differently?
I'm using JpaRepository and method GetReferenceById doesn't throw EntityNotFoundException but getById throwing this exception when object doesn't exists
getReferenceById returns a proxy and doesn't do a database call therefore no exception is called as JPA doesn't know if the entity with this ID exists.
getReferenceById executes EntityManager.getReference and the docs says:
T getReference​(java.lang.Class entityClass, java.lang.Object
primaryKey)
Get an instance, whose state may be lazily fetched. If the
requested instance does not exist in the database, the
EntityNotFoundException is thrown when the instance state is first
accessed. (The persistence provider runtime is permitted to throw the
EntityNotFoundException when getReference is called.) The application
should not expect that the instance state will be available upon
detachment, unless it was accessed by the application while the entity
manager was open.
Source: https://jakarta.ee/specifications/persistence/2.2/apidocs/javax/persistence/entitymanager
Sometimes when using only getById as a way to fetch the entity makes some major issues. Usually we prefer to use getReferenceById method instead to save some extra calls, as if we were doing such using getById there is an extra call to database.
Let’s consider we have a Category child entity that is associated with the parent Product entity via the Product reference in the Category entity. Means each product has multiple categories. The code block that adds a new category to our product using productId as reference is below:
public Category addNewCategory(String categoryName, Long productId) {
Category category = new Category()
.setName(categoryName)
.setProduct(productRepository.findById(productId)
.orElseThrow(
()-> new EntityNotFoundException(
String.format(
"Product with id [%d] was not found!",
productId
)
)
)
);
categoryRepository.save(category);
return category;
}
If you want to add a category to a product, you first need to call findProductById each time you insert a new Category. When you got the Product then you insert it as a reference to the Category entity.
In this case Spring Data JPA would generate the following sql:
SELECT
product0_.id AS id1_0_0_,
product0_.slug AS name2_0_0_,
product0_.title AS title3_0_0_
FROM
product product0_
WHERE
product0_.id = 1
SELECT nextval ('hibernate_sequence')
INSERT INTO category (
product_id,
name,
id
)
VALUES (
1,
'book',
1
)
This query was generated by the findById method call, which is meant to load the entity in the current Persistence Context. However, in our case, we don’t need that. We just want to save a new Category entity and set the product_id Foreign Key column to a value that we already know.
But, since the only way to set the underlying product_id column value is to provide a Product entity reference, that’s why many developers end up calling the findById method.
In our case, running this SQL query is unnecessary because we don’t need to fetch the parent Product entity. But how can we get rid of this extra SQL query?
We can use getReferenceById method instead.
public PostComment addNewCategory(String name, Long productId) {
Category category = new Category()
.setName(name)
.setProduct(productRepository.getReferenceById(productId));
categoryRepository.save(category);
return category;
}
When calling the same addNewCategory method now, we see that the Product entity is no longer fetched as it will be fetched from a cached location where JPA holds entity Proxy. This way we can optimize our Spring applications that uses database intensively.
What you are saying seems a bit odd, as the implementation of the deprecated org.springframework.data.jpa.repository.JpaRepository#getById just delegates to it's replacement, org.springframework.data.jpa.repository.JpaRepository#getReferenceById.
As you can see in the implementation of that method (org.springframework.data.jpa.repository.support.SimpleJpaRepository#getReferenceById) it is directly using the EntityManager#getReference method.
When using Hibernate this normally only creates a Proxy, and just when you access one of the fields the Proxy fetches the real values from the DB - or throwing an EntityNotFoundException in case it does not exist.
Could it be that you changed something in your code, or you are being tricked by your debugger trying to display the toString of your method?

What is difference between session.get() and session.byId().load() in Hibernate?

When an object is written to database and the primary identifier (id) is known, it can be retrieved by the code below:
MyObject myObject = session.get(Class<MyObject>, id);
It seems, there is another way similar to get() method:
IdentifierLoadAccess<MyObject> ila = session.byId(Class<MyObject>);
MyObject myObject = ila.load(id);
I'm looking for a scenario which clarifies differences between them and describes the reason for having two similar methods for the same job in API.
same question can be asked about session.load() and session.byId().getReference().
Edit 1:
According to API documentation:
session.get() and session.byId().load() return persistent instance with given identifier, or null if there is no such persistent instance.
session.load() and session.byId().getReference() might return a proxied instance that is initialized in demand.
IdentifierLoadAccess allows you to specify:
LockOptions
CacheMode
even specifying both of them at once:
Post post = session
.byId( Post.class )
.with( new LockOptions( LockMode.OPTIMISTIC_FORCE_INCREMENT) )
.with( CacheMode.GET )
.load( id );
The same for getting a Proxy reference via getReference(id).
So, they are more flexible than the standard get or load which only take the entity identifier.
The similarity between
MyObject myObject = session.get(Class<MyObject>, id);
and
IdentifierLoadAccess<MyObject> ila = session.byId(Class<MyObject>);
MyObject myObject = ila.load(id);
is that both uses the copncept of hibernate cache mechanism but difference comes in fetching the data from database i.e
When we use session.get(Class,id) data from database comes in cache and you can make changes on that data and will be reflected back in database, as hibernate internally maintains a time stamp cache. This time stamp cache records the time at which a particular Hibernate managed table got modified and before returning the data from entity cache it validate whether the result cache are older with respect to table modification time.
But in case of session.byId().getReference() hibernate uses the concept of natural id in which data from database comes in cache but only onces.If you do any changes on that data using session.save(entity object) approach hibernate will throw an exception and if you do manually modification of table(insert,update,delete) it will not be reflected back when you fetch the data again as it always get the data from cache without checking whether that table for that entity has been modified again or not.
In case of session.get() and session.load() if there is any change in database like (insert,delete,update) of record it will get reflected either in the form of record or null pointer exception if record gets deleted.But in case of session.byId().load() and session.byId().getReference() it will first get the record from database when you try to fetch first time then it will save those record in session and will be shown to user from session only if any (insertion,deletion,updation) occurs then it will not be reflected back
It's mostly used in polymorphic association/queries. assume you have an entity named User with the BillingDetails association. If BillingDetails was mapped with
lazy="true" (which is the default), Hibernate would proxy the association target. In this case, you wouldn’t be able to perform a type-cast to the concrete class CreditCard (which is a subclass of BillingDetails) at runtime, and even the instanceof operator would behave strangely:
User user = (User) session.get(User.class, userid);
BillingDetails bd = user.getDefaultBillingDetails();
System.out.println( bd instanceof CreditCard ); // Prints "false"
CreditCard cc = (CreditCard) bd; // ClassCastException!
To perform a proxy-safe typecast, use load()
User user = (User) session.get(User.class, userId);
BillingDetails bd = user.getDefaultBillingDetails();
// Narrow the proxy to the subclass, doesn't hit the database
CreditCard cc =
(CreditCard) session.load( CreditCard.class, bd.getId() );
expiryDate = cc.getExpiryDate();
Note that you can avoid these issues by avoiding lazy fetching, as in the follow-ing code, using an eager fetch query
User user = (User)session.createCriteria(User.class)
.add(Restrictions.eq("id", uid) )
.setFetchMode("defaultBillingDetails", FetchMode.JOIN)
.uniqueResult();
// The users defaultBillingDetails have been fetched eagerly
CreditCard cc = (CreditCard) user.getDefaultBillingDetails();
expiryDate = cc.getExpiryDate();
Truly object-oriented code shouldn’t use instanceof or numerous typecasts. If you find yourself running into problems with proxies, you should question your design, asking whether there is a more polymorphic approach.
The key difference between get() and load() method is that load() will throw an exception if an object with id passed to them is not found, but get() will return null. Another important difference is that load can return proxy without hitting the database unless required (when you access any attribute other than id) but get() always go to the database, so sometimes using load() can be faster than the get() method. It makes sense to use the load() method if you know the object exists but get() method if you are not sure about object's existence.

What is the difference between EntityManager.find() and EntityManger.getReference()?

Whats is the difference between
<T> T EntityManager.find(Class<T> entityClass, Object primaryKey) and
<T> T EntityManager.getReference(Class<T> entityClass, Object primaryKey)
?
I think getReference returns entity if it is managed.
and find returns entity if it is managed else executes SQL on database to make it managed.
Please confirm.
Context:
From webapp I get primary key of object to be deleted (pk of type long); to entity should be managed to delete.
EntityManager.remove(Object entity)
to pass managed entity to entitymanager remove method 'whats the better and correct option? find or getReference?'
JPA has the concept of an EntityManager, as you know. During your work in the entity manager some objects are loaded from the database, can be modified and afterwards flushed to the database.
find() has to return an initialized instance of your object. If it is not already loaded in the EntityManager, it is retrieved from the database.
getReference() is allowed to return a proxy instead of an initialized instance, if the entity has not been loaded in the EntityManager before. In this proxy, only the primary key attribute is initialized. Proxies can be created without hitting the database, because the only initialized attribute is already given to the getReference() function.
The latter is useful when you have an entity A referencing an entity B, and you want to set the b-attribute of A to B, without having to load B from the database.
Only if you reference other attributes of B, the proxy will be initialized.
The book Beginning Java EE 6 Platform with GlassFish 3, mention the differences in page 135: "Finding By ID"
find() if the entity is found, it is returned; if it is not found, a null value is returned.
MyEntity obj = em.find(MyEntity.class, id);
if(obj != null){
// Process the object
}
getReference() is intended for situations where a managed entity instance is needed, but no data, other than potentially the entity's primary key, being accessed.
try {
MyEntity obj = em.getReference(MyEntity.class, id);
// Process the object
} catch (EntityNotFoundException e) {
// Entity Not Found
}
getReference() does not retrieve the full object but only a proxy and therefore can be more efficient if you do not access the members of the object.
For instance when creating a new object to insert into your database, it might have to refer to another object which already has been stored in the database.
For JPA to store the new object correctly only the primary key of the referred object is needed.
By using getReference() you get a proxy which contains the primary key and you save the cost of loading the complete object.

What Query should i use in Hibernate to fetch POJO?

I learnt Hibernate and used it to reduce my Java code to a vast extent and also able
to reduce the time spent for DB's. Now what type of query should i use to finish my
operations for getting a DB list to be displayed, to update and delete.
My code for deletion is
String newToken = "DELETEUSER";
if(!TokenManager.checkRoleToken(newToken)){
return;
}
Session session = Main.getSession(); //calling the main method to get sesion
Leavetable table = new Leavetable; // intialisation of object table
try{
Transaction tr = session.beginTransaction();
table = session.createQuery();
session.delete(table); // deletion of the object and its properties from selected leaveID
tr.commit();
}
finally{
session.close();
}
My code for Db updation
public void updateLeaveTable( Leavetable leave ) {
String newToken = "ADDUSER";
if( !TokenManager.checkRoleToken( newToken ) ) {
return;
}
Session session = Main.getSession(); // calling the main method to get
// session
try {
session = Main.getSession();
Transaction tr = session.beginTransaction();
session.saveOrUpdate( leave ); // here without query the table gets
// updated How?
tr.commit();
}
finally {
session.close();
}
}
What type of query should I follow. My final task before going into project. When I
know this will start my life as a developer. Any suggestions Please.
Do you mean a HQL query? Well, a typical query on your Leavetable entity would looks like this:
Query q = session.createQuery("from Leavetable t where t.someField = :value");
q.setParameter("value", foo);
List<Leavetable> results = q.list();
However, if you just want to retrieve an entity by identifier, see Session#load() or Session#get(). I don't want to make things too much confusing but while both methods are similar, there is an important difference between both of them. Quoting the Hibernate Forums:
Retrieving objects by identifier
The following Hibernate code snippet
retrieves a User object from the
database:
User user = (User) session.get(User.class, userID);
The get() method is special because
the identifier uniquely identifies a
single instance of a class. Hence it’s
common for applications to use the
identifier as a convenient handle to a
persistent object. Retrieval by
identifier can use the cache when
retrieving an object, avoiding a
database hit if the object is already
cached. Hibernate also provides a
load() method:
User user = (User) session.load(User.class, userID);
The load() method is older; get() was
added to Hibernate’s API due to user
request. The difference is trivial:
If load() can’t find the object in
the cache or database, an exception is
thrown. The load() method never
returns null. The get() method
returns null if the object can’t be
found.
The load() method may return a proxy
instead of a real persistent instance.
A proxy is a placeholder that triggers
the loading of the real object when
it’s accessed for the first time; we
discuss proxies later in this section.
On the other hand, get() never
returns a proxy.
Choosing between get() and load()
is easy: If you’re certain the
persistent object exists, and
nonexistence would be considered
exceptional, load() is a good
option. If you aren’t certain there is
a persistent instance with the given
identifier, use get() and test the
return value to see if it’s null.
Using load() has a further
implication: The application may
retrieve a valid reference (a proxy)
to a persistent instance without
hitting the database to retrieve its
persistent state. So load() might
not throw an exception when it doesn’t
find the persistent object in the
cache or database; the exception would
be thrown later, when the proxy is
accessed.
Of course, retrieving an object by
identifier isn’t as flexible as using
arbitrary queries.
See also the Hibernate Documentation (links below).
Reference
Hibernate Core Reference Guide
10.3. Loading an object
Chapter 14. HQL: The Hibernate Query Language

Categories