Showing posts with label JPA. Show all posts
Showing posts with label JPA. Show all posts

Tuesday, March 27, 2018

Could not write content: Infinite recursion (StackOverflowError) (through reference chain: org.hibernate.collection.internal.PersistentBag[0]

The problem., I was getting a wrong JSON response while using a many-to-many relationship, that caused my application to enter in an infinite loop giving as output an infinite recursion Stackoverflow error.
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).
How does serialization work? (The solution in theory)
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.
The solution in practice.
It's very simple. Assuming that your database query already works without JSON, all you have to do is this:
  1. 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>();
    
    ...
    
  2. 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)


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.
  1. Disable query cache
To disable the query cache (default), set the openjpa.QueryCache property to false:
<property name="openjpa.QueryCache" value="false"/>
  1. 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"/>

  1. Open JPA - L2 Cache Issue and Workaround
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

  1. Several mechanisms are available to the application to bypass SQL caching for a JPQL query.
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) 
  1. Plug-in property openjpa.jdbc.QuerySQLCache can 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, April 19, 2016

OpenJpa second level caching


  1.  http://openjpa.apache.org/builds/1.2.3/apache-openjpa/docs/ref_guide_caching.html
  2. http://openjpa.apache.org/builds/1.2.3/apache-openjpa/docs/ref_guide_caching.html#ref_guide_cache_pmevict
  3. https://www.ibm.com/support/knowledgecenter/was_beta/com.ibm.websphere.base.doc/ae/tejb_datcacheconfig.html
  4. https://www.ibm.com/support/knowledgecenter/SSAW57_8.0.0/com.ibm.websphere.nd.doc/info/ae/ae/rdyn_openjpa.html
  5. http://www.developer.com/java/using-second-level-caching-in-a-jpa-application.html
  6. http://docs.oracle.com/javaee/6/tutorial/doc/gkjjj.html
  7. http://blog.jhades.org/setup-and-gotchas-of-the-hibernate-second-level-and-query-caches/
  8. http://www.javalobby.org/java/forums/t48846.html
  9. http://docs.jboss.org/hibernate/orm/3.5/reference/en/html/performance.html
  10. http://www.coderpanda.com/jpa-caching/
  11. 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.

You can use Prepared Statements wrong like this:
Code:
String strUserName = request.getParameter("Txt_UserName");
 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();