Showing posts with label JPA. Show all posts
Showing posts with label JPA. Show all posts
Wednesday, April 25, 2018
Best Tutorial: Many-many relationship with extra columns in JPA
Friday, April 20, 2018
Tuesday, March 27, 2018
Could not write content: Infinite recursion (StackOverflowError) (through reference chain: org.hibernate.collection.internal.PersistentBag[0]
Here is part of what I found in my Eclipse console:
Request processing failed; nested exception is org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError) (through reference chain: [here is the loop]) with root cause java.lang.StackOverflowError at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:567) at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:143) at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:118) at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:24) at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:180) at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:544) at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:551) ...
and so on.
As the docs state (see references),
bi-directional references for ORM-managed beans (iBatis, Hibernate) would cause serialization to failure since they are cyclic dependencies. Since Jackson 1.6, this problem has been solved by the introduction of two new annotations: @JsonManagedReference and @JsonBackReference(and see the end of this post to give a look at the @JsonIdentityInfo annotation).
In computer science, in the context of data storage and transmission, serialization is the process of translating data structures or object state into a format that can be stored (for example, in a file or memory buffer, or transmitted across a network connection link) and resurrected later in the same or another computer environment.
For Jackson to work well, one of the two sides of the relationship should not be serialized, in order to avoid the annoying infinite recursive loop that causes our stackoverflow error.
So, Jackson takes the forward part of the reference, for example an attribute of a java class (i.e. List<Role> roles in User class), and converts it in a json-like storage format; this is the so-called marshalling process.
Then, Jackson looks for the back part of the reference (i.e. List<User> users in Role class) and leaves it as it is, not serializing it. This part of the relationship will be re-constructed during the deserialization (unmarshalling) of the forward reference.
Then, Jackson looks for the back part of the reference (i.e. List<User> users in Role class) and leaves it as it is, not serializing it. This part of the relationship will be re-constructed during the deserialization (unmarshalling) of the forward reference.
It's very simple. Assuming that your database query already works without JSON, all you have to do is this:
- Add the @JsonManagedReference In the forward part of the relationship (i.e. User.java class):
@Entity public class User implements java.io.Serializable{ @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private long id; @Column(name="name") private String name; @ManyToMany @JoinTable(name="users_roles",joinColumns=@JoinColumn(name = "user_fk"), inverseJoinColumns=@JoinColumn(name = "role_fk")) @JsonManagedReference private Set<Role> roles = new HashSet<Role>(); ... - Add the @JsonBackReference In the back part of the relationship (i.e. Role.java class):
@Entity public class Role implements java.io.Serializable { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int id; @ManyToMany(mappedBy="roles") @JsonBackReference private Set<User> users = new HashSet<User>(); ...
The work is done. If you take a look at your firebug logs, you'll notice that the infinite recursive loop has disappeared.
Resource Link:
How To Solve JSON infinite recursion Stackoverflow (with Spring and Jackson annotations)
Friday, February 23, 2018
Best Spring Data JPA tutorial
Blog:
- https://medium.com/@joeclever/using-multiple-datasources-with-spring-boot-and-spring-data-6430b00c02e7
- https://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-three-custom-queries-with-query-methods/
- https://stackoverflow.com/questions/9314078/setmaxresults-for-spring-data-jpa-annotation
- https://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-part-two-crud/
- https://scattercode.co.uk/2016/01/05/multiple-databases-with-spring-boot-and-spring-data-jpa/
Github:
Sunday, December 3, 2017
Difference between Spring Data JPA's findFirst and findTop?
Limiting query results
The results of query methods can be limited via the keywords
first or top, which can be used interchangeably. An optional numeric value can be appended to top/first to specify the maximum result size to be returned. If the number is left out, a result size of 1 is assumed.Limiting the result size of a query with Top and First
User findFirstByOrderByLastnameAsc();
User findTopByOrderByAgeDesc();
Page<User> queryFirst10ByLastname(String lastname, Pageable pageable);
Slice<User> findTop3ByLastname(String lastname, Pageable pageable);
List<User> findFirst10ByLastname(String lastname, Sort sort);
List<User> findTop10ByLastname(String lastname, Pageable pageable);
The limiting expressions also support the
Distinct keyword. Also, for the queries limiting the result set to one instance, wrapping the result into an Optional is supported.OpenJpa query caching is not refreshing in case of null value - How to resolve this issue?
Solution:
So far it is not fixed yet. But they have given some bypassing solution.
- Disable query cache
To disable the query cache (default), set the
openjpa.QueryCache property to false:<property name="openjpa.QueryCache" value="false"/>
- By configuring sql query cache to false
- To specify a custom cache class:
<property name="openjpa.jdbc.QuerySQLCache" value="com.mycompany.MyCustomCache"/> - To use an unmanaged cache:
<property name="openjpa.jdbc.QuerySQLCache" value="false"/>
OR- To use an unmanaged cache:
<property name="openjpa.jdbc.QuerySQLCache" value="all"/>
This tutorial depicts your problem same to same. Here you can get the clear conception of occuring this error.
It gives a solution that you must have to keep related data. So that
NullPointerException will not arise. Data must be consistent until OpenJPA not solve the issue. :D
A user application can disable Prepared SQL Cache for entire lifetime of a persistence context by invoking the following method on OpenJPA's EntityManager SPI interface:
OpenJPAEntityManagerSPI.setQuerySQLCache(boolean)
- Plug-in property
openjpa.jdbc.QuerySQLCachecan be configured to exclude certain JPQL queries as shown below.<property name="openjpa.jdbc.QuerySQLCache" value="true(excludes='select c from Company c;select d from Department d')"/>
will never cache JPQL queries
select c from Company c and select d from Department d.Root Cause Analysis:
The query cache stores the object IDs that are returned by query executions. When you run a query, JPA assembles a key that is based on the query properties and the parameters that are used at launch time and checks for a cached query result. If one is found, the object IDs in the cached result are looked up, and the resulting persistence-capable objects are returned. Otherwise, the query is launched against the database and the object IDs that are loaded by the query are placed into the cache. The object ID list is not cached until the list that is returned at query launch time is fully traversed.
IBM Recommendation:
L2 caching increases the memory consumption of the application, therefore, it is important to limit the size of the L2 cache. There is also a possibility of stale data for updated objects in a clustered environment. Configure L2 caching for read-mostly, infrequently modified entities. L2 caches are not recommended for frequently and concurrently updated entities.
Resource Link:
Wednesday, October 19, 2016
How does EJB and JPA relate?
JPA has been designed to
replace EJB2 entity beans, and has started as a part of the EJB3 specification.
Since it makes sense to
also use JPA outside of an EJB container, it has now its own specification, but
it's still related to EJB3, since a compliant EJB3 container has to provide a
JPA implementation, which integrates into the transaction handling of the
container.
EJB2 had
"entity beans" which were a third type of component. EJB3 has JPA,
which has "entities". But I don't think they're considered as
"EJB components" anymore. They're just called JPA entities.
2.
Up until version 2.1 of the EJB specifications, an entity bean
class had to implement the
javax.ejb.EntityBean interface
and provide an implementation for boilerplate methods such as ejbLoad,
ejbStore, ejbActivate, and ejbPassivate.
EJB 3.0
adopted the JPA specification. The very notion of an entity bean was superceded
by the simpler notion of a JPA entity. To create such entity, no interface
implementation or boiler plate methods are required. The entity is a POJO that
has the
@Entity annotation.
Thus, in practice the use of "entity bean" EJBs in
Java EE applications is dead (buried under JPA) as of EJB 3.
You are right. JPA has
more to do than only supporting EJB. Thats the reason why JPA became a separate
JSR or specification. EJB uses or enables the usage of JPA in its
specification, simply because JPA is a good standard. You can now switch
between JPA vendors without changing your code if designed properly.
EJB specification can be
used independent of JPA (although JPA has been included as a part of EJB spec)
and likewise JPA can be used for many more stuff outside the EJB spec.
Nevertheless, EJB specification enables the injection of JPA Entitiy Manager
(and its usage) into its beans very easily which makes programming easier.
Ofcourse this can now be achieved easily using a new JSR on CDI :-).
All
the application server that supports EJB spec, should support JPA also. You can
see this threadfor
more information.
Hibernate is an implementation of the JPA spec.
Pros of Agile methods
- Working software is delivered much more quickly and successive iterations can be delivered frequently, at a consistent pace.
- There is closer collaboration between developers and the business.
- Changes to requirements can be incorporated at any point of the process – even late in development.
- It gives the opportunity for continuous improvement for live systems
- It is highly transparent
Pros of the
waterfall method
·
Potential issues that would have
been found during development can be researched and bottomed out during the
design phase. If appropriate meaning an alternate solution is selected before
any code is written.
·
The development process tends to
be better documented since this methodology places greater emphasis on
documentation like requirements and design docs. Many organisations find this
reassuring.
·
Because the waterfall process is a
linear one it is perhaps easier to understand, especially for non-developers or
those new to software development. Often teams feel more comfortable with this
approach.
Cons of the waterfall
method
·
Often the people we’re building
software for (the client) don’t know exactly what they need up front and don’t
know what’s possible with the technology available. This way of working doesn’t
handle this well.
·
Solution designers often aren’t
able to foresee problems that will arise out of the implementation of their
designs.
·
Changes to requirements (e.g. like
those resulting from new technologies, changes in a market or changes to
business goals) can’t easily be incorporated with the waterfall method and
there are often laborious change control procedures to go through when this
happens
·
The process doesn’t have its own
momentum
Tuesday, October 4, 2016
Tuesday, May 3, 2016
Hibernate Merge
- http://stackoverflow.com/questions/1069992/jpa-entitymanager-why-use-persist-over-merge?rq=1
- http://techblog.bozho.net/how-does-merge-work-in-jpa-and-hibernate/
- https://hibernate.atlassian.net/browse/HHH-5855
- https://github.com/hibernate/hibernate-orm/pull/1212
- http://www.programmingforfuture.com/2011/02/hibernate-merge-may-insert-new-record.html
- https://gopinathb4u.wordpress.com/2011/07/26/duplicate-child-inserts-during-merge-operation-in-hibernate/
Hibernate Tutorial
Tuesday, April 19, 2016
OpenJpa second level caching
- http://openjpa.apache.org/builds/1.2.3/apache-openjpa/docs/ref_guide_caching.html
- http://openjpa.apache.org/builds/1.2.3/apache-openjpa/docs/ref_guide_caching.html#ref_guide_cache_pmevict
- https://www.ibm.com/support/knowledgecenter/was_beta/com.ibm.websphere.base.doc/ae/tejb_datcacheconfig.html
- https://www.ibm.com/support/knowledgecenter/SSAW57_8.0.0/com.ibm.websphere.nd.doc/info/ae/ae/rdyn_openjpa.html
- http://www.developer.com/java/using-second-level-caching-in-a-jpa-application.html
- http://docs.oracle.com/javaee/6/tutorial/doc/gkjjj.html
- http://blog.jhades.org/setup-and-gotchas-of-the-hibernate-second-level-and-query-caches/
- http://www.javalobby.org/java/forums/t48846.html
- http://docs.jboss.org/hibernate/orm/3.5/reference/en/html/performance.html
- http://www.coderpanda.com/jpa-caching/
- http://tech.puredanger.com/2009/07/10/hibernate-query-cache/
When Query cache is bypassed?
The evictAll method with no arguments clears the cache.
Most caches are of limited size. Pinning an identity to the cache ensures that the cache will not kick the data for the corresponding instance out of the cache, unless you manually evict it.
StoreCache Usage
import org.apache.openjpa.persistence.*;
...
OpenJPAEntityManagerFactory oemf = OpenJPAPersistence.cast(emf);
StoreCache cache = oemf.getStoreCache();
cache.pin(Magazine.class, popularMag.getId());
cache.evict(Magazine.class, changedMag.getId());
Wednesday, February 24, 2016
SQL Injection and how to prevent it? Hibernet/JPA/SQL
SQL Injection
1. Prepared Statement and Callable Statement:
A
PreparedStatement represents a precompiled SQL statement that can be executed
multiple times without having to recompile for every execution.
Secure
Code:
PreparedStatement
stmt = connection.prepareStatement("SELECT * FROM users WHERE userid=? AND
password=?");
stmt.setString(1, userid);
stmt.setString(2, password);
ResultSet rs = stmt.executeQuery();
Why this
code is secure?
Ans: This code is not vulnerable to SQL Injection because it correctly
uses parameterized queries. By utilizing Java's PreparedStatement class, bind
variables (i.e. the question marks) and the corresponding setString methods,
SQL Injection can be easily prevented.
Vulnerable
Code 1:
//
Example #1
String query = "SELECT * FROM users WHERE userid ='"+
userid + "'" + " AND password='" + password +
"'";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);
Why this
code is vulnerable?
Ans: This code is vulnerable to SQL Injection because it uses dynamic
queries to concatenate malicious data to the query itself. Notice that it uses
the Statement class instead of the PreparedStatement class.
Vulnerable
Code 2:
// Example #2
String query = "SELECT * FROM users WHERE userid ='"+
userid + "'" + " AND password='" + password +
"'";
PreparedStatement stmt = connection.prepareStatement(query);
ResultSet rs = stmt.executeQuery();
Why this
code is vulnerable?
Ans: This code is also vulnerable to SQL Injection. Even though it uses
the PreparedStatement class it is still creating the query dynamically via
string concatenation.
2. Hibernate:
How to Fix SQL Injection using Hibernate?
Hibernate facilitates the storage and
retrieval of Java domain objects via Object/Relational Mapping (ORM). It is a
very common misconception that ORM solutions, like hibernate, are SQL Injection
proof. Hibernate allows the use of "native SQL" and defines a
proprietary query language, named, HQL (Hibernate Query Language); the former
is prone to SQL Injection and the later is prone to HQL (or ORM) injection.
This article is intended to illustrate
how certain syntax offered by hibernate to define SQL & HQL, is better over
the other, in terms of defense against SQL and/or HQL injection attacks.
Secure Usage:
Code-1:
/* Positional parameter in HQL */
Query hqlQuery = session.createQuery("from Orders as orders
where orders.id = ?");
List results = hqlQuery.setString(0,
"123-ADB-567-QTWYTFDL").list();
Code-2:
/* named parameter in HQL */
Query hqlQuery = session.createQuery("from Employees as emp
where emp.incentive > :incentive");
List results = hqlQuery.setLong("incentive", new
Long(10000)).list();
Code-3:
/* named parameter list in HQL */
List items = new ArrayList();
items.add("book"); items.add("clock");
items.add("ink");
List results = session.createQuery("from Cart as cart where
cart.item in (:itemList)").setParameterList("itemList",
items).list();
Code-4:
/* JavaBean in HQL */
Query hqlQuery = session.createQuery("from Books as books
where book.name = :name and book.author = :author");
List results = hqlQuery.setProperties(javaBean).list();
//assumes javaBean has getName() & getAuthor() methods.
Code-5:
/* Native-SQL */
Query sqlQuery = session.createSQLQuery("Select * from
Books where author = ?");
List results = sqlQuery.setString(0, "Charles
Dickens").list();
Why
above 5 codes are secure ?
Ans:
The above code snippets use
parameter binding to set data. The JDBC driver will escape this data appropriately before the query
is executed, making sure that data is used just as data.
Assuming data used in the above code
snippets is user input, that has not been validated or escaped and it contains
malicious database code (payload), the payload will be escaped appropriately by
the JDBC driver (since parameterized queries are used), such that it would be
used as data and not as code.
Vulnerable
Code:
List
results = session.createQuery("from Orders as orders where orders.id =
" + currentOrder.getId()).list();
List results = session.createSQLQuery("Select * from Books
where author = " + book.getAuthor()).list();
Why this
code is vulnerable ?
Ans:
Assuming orderId
and author are user input that have not been
validated or escaped, it leaves the above queries vulnerable to SQL and
HQL(ORM) injection attacks.
3. Java Persistence API(JPA):
How to Fix SQL Injection using the Java Persistence API (JPA) ?
Java Persistence API (JPA), is an ORM
solution that is a part of the Java EE framework. It helps manage relational
data in applications that use Java SE and Java EE. It is a common misconception
that ORM solutions like JPA (Java Persistence API) are SQL Injection proof. JPA
allows the use of native SQL and defines its own query language, named, JPQL
(Java Persistence Query Language). The former is prone to traditional SQL
injection attacks and the later is prone to JPQL (or ORM) injection attacks.
This article is intended to illustrate
how certain syntax offered by JPA to define SQL & HQL, is better over the
other, in terms of defense against SQL and/or HQL injection attacks.
Secure usage:
Code-1:
/* positional parameter in JPQL */
Query jpqlQuery = entityManager.createQuery("Select order
from Orders order where order.id = ?1");
List results =
jpqlQuery.setParameter(1,"123-ADB-567-QTWYTFDL").getResultList();
Code-2:
/* named parameter in JPQL */
Query jpqlQuery = entityManager.createQuery("Select emp
from Employees emp where emp.incentive > :incentive");
List results = jpqlQuery.setParameter("incentive",
new Long(10000)).getResultList();
Code-3:
/* named query in JPQL - Query named "myCart" being
"Select c from Cart c where c.itemId = :itemId" */
Query jpqlQuery =
entityManager.createNamedQuery("myCart");
List results = jpqlQuery.setParameter("itemId",
"item-id-0001").getResultList();
Code-4:
/* Native SQL */
Query sqlQuery = entityManager.createNativeQuery("Select *
from Books where author = ?", Book.class);
List results = sqlQuery.setParameter(1, "Charles
Dickens").getResultList();
Why
above 4 codes are secure ?
Ans:
The above code snippets use parameter
binding to set data. The JDBC driver will escape this data appropriately before the query
is executed; making sure that data is used just as data.
Assuming data used in the above code
snippets is user input, that has not been validated or escaped and it contains
malicious database code (payload), the payload will be escaped appropriately by
the JDBC driver (since parameterized queries are used), such that it would be
used as data and not as code.
Vulnerable
Code:
List
results = entityManager.createQuery("Select order from Orders order where
order.id = " + orderId).getResultList();
List results = entityManager.createNativeQuery("Select *
from Books where author = " + author).getResultList();
int resultCode = entityManager.createNativeQuery("Delete
from Cart where itemId = " + itemId).executeUpdate();
Why this
code is vulnerable ?
Ans:
Assuming orderId, author & itemId
are user input that have not been validated or escaped as required, it leaves
the above queries vulnerable to SQL and JPQL (ORM) injection attacks.
Code:
String strUserName =
request.getParameter("Txt_UserName");
PreparedStatement prepStmt = con.prepareStatement("SELECT * FROM user WHERE userId = '+strUserName+'");
PreparedStatement prepStmt = con.prepareStatement("SELECT * FROM user WHERE userId = '+strUserName+'");
So be sure to use Prepared Statements WITH ALL Bind Variables.
Code:
String selectStatement = "SELECT * FROM User WHERE userId =
? ";
PreparedStatement prepStmt = con.prepareStatement(selectStatement);
prepStmt.setString(1, userId);
ResultSet rs = prepStmt.executeQuery();
PreparedStatement prepStmt = con.prepareStatement(selectStatement);
prepStmt.setString(1, userId);
ResultSet rs = prepStmt.executeQuery();
Subscribe to:
Posts (Atom)