How to map JSON objects using generic Hibernate Types

Introduction

Since not all relational database systems support JSON types, Hibernate does not come with a built-in JSON Type mapper. Traditionally, all custom types have been supplied via a UserType implementation. However, a UserType is not very developer friendly so, in this post, I’m going to show how you can do a better job using AbstractSingleColumnStandardBasicType instead.

The Domain Model

Assuming we have the following Domain Model:

JsonTypeDomainModel

Location and Ticket are JSON Object(s), while Event and Participant are JPA entities. Our goal is to provide a Hibernate JSON Type that works for any type of JSON Java Object and on any relational database that supports JSON columns.

Generic JSON Types

First of all, we need a Jackson-based utility to allows us to easily transform JSON Object(s) to and from String:

public class JacksonUtil {

    public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    public static <T> T fromString(String string, Class<T> clazz) {
        try {
            return OBJECT_MAPPER.readValue(string, clazz);
        } catch (IOException e) {
            throw new IllegalArgumentException("The given string value: " 
                + string + " cannot be transformed to Json object");
        }
    }

    public static String toString(Object value) {
        try {
            return OBJECT_MAPPER.writeValueAsString(value);
        } catch (JsonProcessingException e) {
            throw new IllegalArgumentException("The given Json object value: " 
                + value + " cannot be transformed to a String");
        }
    }

    public static JsonNode toJsonNode(String value) {
        try {
            return OBJECT_MAPPER.readTree(value);
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }
    }

    public static <T> T clone(T value) {
        return fromString(toString(value), (Class<T>) value.getClass());
    }
}

There are two ways to send a JSON Object to the database:

  • using a String
  • using a binary representation of the actual JSON Object

For this reason, we are going to implement two types: JsonBinaryType and JsonStringType.

JsonBinaryType

The binary type looks as follows:

public class JsonBinaryType
    extends AbstractSingleColumnStandardBasicType<Object> 
    implements DynamicParameterizedType {

    public JsonBinaryType() {
        super( 
            JsonBinarySqlTypeDescriptor.INSTANCE, 
            new JsonTypeDescriptor()
        );
    }

    public String getName() {
        return "jsonb";
    }

    @Override
    public void setParameterValues(Properties parameters) {
        ((JsonTypeDescriptor) getJavaTypeDescriptor())
            .setParameterValues(parameters);
    }

}

JsonStringType

The String Type looks like this:

public class JsonStringType
        extends AbstractSingleColumnStandardBasicType<Object> 
        implements DynamicParameterizedType {

    public JsonStringType() {
        super( 
            JsonStringSqlTypeDescriptor.INSTANCE, 
            new JsonTypeDescriptor() 
        );
    }

    public String getName() {
        return "json";
    }

    @Override
    protected boolean registerUnderJavaType() {
        return true;
    }

    @Override
    public void setParameterValues(Properties parameters) {
        ((JsonTypeDescriptor) getJavaTypeDescriptor())
            .setParameterValues(parameters);
    }
}

Both types extend the AbstractSingleColumnStandardBasicType Hibernate built-in Type base class and any JSON Object is accepted. By implementing the DynamicParameterizedType interface, we can extract the underlying JSON Object Java Class, which is needed when reconstructing the JSON Object from its String representation.

The AbstractSingleColumnStandardBasicType constructor takes two parameters:

  • a sqlTypeDescriptor,
  • a javaTypeDescriptor

JsonTypeDescriptor

Both JsonBinaryType and JsonStringType use the same JsonTypeDescriptor which is responsible for transforming the JSON Object type used in the entity mapping classes to a format that is supported by the underlying database.

public class JsonTypeDescriptor
        extends AbstractTypeDescriptor<Object> 
        implements DynamicParameterizedType {

    private Class<?> jsonObjectClass;

    @Override
    public void setParameterValues(Properties parameters) {
        jsonObjectClass = ( (ParameterType) parameters.get( PARAMETER_TYPE ) )
            .getReturnedClass();

    }

    public JsonTypeDescriptor() {
        super( Object.class, new MutableMutabilityPlan<Object>() {
            @Override
            protected Object deepCopyNotNull(Object value) {
                return JacksonUtil.clone(value);
            }
        });
    }

    @Override
    public boolean areEqual(Object one, Object another) {
        if ( one == another ) {
            return true;
        }
        if ( one == null || another == null ) {
            return false;
        }
        return JacksonUtil.toJsonNode(JacksonUtil.toString(one)).equals(
                JacksonUtil.toJsonNode(JacksonUtil.toString(another)));
    }

    @Override
    public String toString(Object value) {
        return JacksonUtil.toString(value);
    }

    @Override
    public Object fromString(String string) {
        return JacksonUtil.fromString(string, jsonObjectClass);
    }

    @SuppressWarnings({ "unchecked" })
    @Override
    public <X> X unwrap(Object value, Class<X> type, WrapperOptions options) {
        if ( value == null ) {
            return null;
        }
        if ( String.class.isAssignableFrom( type ) ) {
            return (X) toString(value);
        }
        if ( Object.class.isAssignableFrom( type ) ) {
            return (X) JacksonUtil.toJsonNode(toString(value));
        }
        throw unknownUnwrap( type );
    }

    @Override
    public <X> Object wrap(X value, WrapperOptions options) {
        if ( value == null ) {
            return null;
        }
        return fromString(value.toString());
    }

}

The jsonObjectClass holds the underlying entity mapping JSON Object type. The toString and fromString methods allow Hibernate to converts a JSON Object to a String and to reconstruct a JSON Object from its String representation.

The unwrap method is used prior to materializing the JSON Object to a format that is expected by the currently used relational database. For this reason, we can unwrap a JSON Object to either a String or a JsonNode.

The MutableMutabilityPlan specifies that the JSON Object can be updated, and the areEqual method determines if two JSON Object(s) are equivalent.

AbstractJsonSqlTypeDescriptor

Both the JsonBinarySqlTypeDescriptor and the JsonStringSqlTypeDescriptor classes extend from a common AbstractJsonSqlTypeDescriptor which looks like this:

public abstract class AbstractJsonSqlTypeDescriptor 
    implements SqlTypeDescriptor {

    @Override
    public int getSqlType() {
        return Types.OTHER;
    }

    @Override
    public boolean canBeRemapped() {
        return true;
    }

    @Override
    public <X> ValueExtractor<X> getExtractor(
        final JavaTypeDescriptor<X> javaTypeDescriptor) {
        return new BasicExtractor<X>(javaTypeDescriptor, this) {
            @Override
            protected X doExtract(
                ResultSet rs, 
                String name, 
                WrapperOptions options) throws SQLException {
                return javaTypeDescriptor.wrap(
                    rs.getObject(name), options
                );
            }

            @Override
            protected X doExtract(
                CallableStatement statement, 
                int index, 
                WrapperOptions options) throws SQLException {
                return javaTypeDescriptor.wrap(
                    statement.getObject(index), options
                );
            }

            @Override
            protected X doExtract(
                CallableStatement statement, 
                String name, 
                WrapperOptions options) throws SQLException {
                return javaTypeDescriptor.wrap(
                    statement.getObject(name), options
                );
            }
        };
    }

}

The AbstractJsonSqlTypeDescriptor base class allows us to notify Hibernate that the expected JDBC type is not a SQL-standard column type, as well as the ResultSet extraction logic.

JsonBinarySqlTypeDescriptor

For relational databases that expect to materialize the JSON Object in a binary format, we need to use the JsonBinarySqlTypeDescriptor:

public class JsonBinarySqlTypeDescriptor
    extends AbstractJsonSqlTypeDescriptor {

    public static final JsonBinarySqlTypeDescriptor INSTANCE = 
        new JsonBinarySqlTypeDescriptor();

    @Override
    public <X> ValueBinder<X> getBinder(
        final JavaTypeDescriptor<X> javaTypeDescriptor) {
        return new BasicBinder<X>(javaTypeDescriptor, this) {
            @Override
            protected void doBind(
                PreparedStatement st, 
                X value, 
                int index, 
                WrapperOptions options) throws SQLException {
                st.setObject(index, 
                    javaTypeDescriptor.unwrap(
                        value, JsonNode.class, options), getSqlType()
                );
            }

            @Override
            protected void doBind(
                CallableStatement st, 
                X value, 
                String name, 
                WrapperOptions options)
                    throws SQLException {
                st.setObject(name, 
                    javaTypeDescriptor.unwrap(
                        value, JsonNode.class, options), getSqlType()
                );
            }
        };
    }
}

As you can see, the JSON Object is sent as a JsonNode using the setObject method exposed by either PreparedStatement or CallableStatement.

JsonStringSqlTypeDescriptor

For relational databases that expect to materialize the JSON Object in a String-like format, we need to use the JsonStringSqlTypeDescriptor:

public class JsonStringSqlTypeDescriptor 
    extends AbstractJsonSqlTypeDescriptor {

    public static final JsonStringSqlTypeDescriptor INSTANCE = 
        new JsonStringSqlTypeDescriptor();

    @Override
    public <X> ValueBinder<X> getBinder(
        final JavaTypeDescriptor<X> javaTypeDescriptor) {
        return new BasicBinder<X>(javaTypeDescriptor, this) {
            @Override
            protected void doBind(
                PreparedStatement st, 
                X value, 
                int index, 
                WrapperOptions options) throws SQLException {
                st.setString(index, 
                    javaTypeDescriptor.unwrap(value, String.class, options)
                );
            }

            @Override
            protected void doBind(
                CallableStatement st, 
                X value, 
                String name, 
                WrapperOptions options)
                    throws SQLException {
                st.setString(name, 
                    javaTypeDescriptor.unwrap(value, String.class, options
                ));
            }
        };
    }
}

As you can see, the JSON Object is sent as a String using the setString method exposed by either PreparedStatement or CallableStatement.

Testing time

These two generic JSON Types work on either PostgreSQL or MySQL. To make use of the newly defined types, we must declare them using the TypeDef annotation:

@TypeDefs({
    @TypeDef(name = "json", typeClass = JsonStringType.class),
    @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
})
@MappedSuperclass
public class BaseEntity { }

The `TypeDef` annotations can be applied to a base entity class or in the package-info.java file associated to our current entities package.

MySQL

MySQL 5.7 adds support for JSON types which, at the JDBC level, need to be materialized as String. For this reason we are going to use JsonStringType.

The entity mapping looks like this:

@Entity(name = "Event") @Table(name = "event")
public static class Event extends BaseEntity {

    @Type(type = "json")
    @Column(columnDefinition = "json")
    private Location location;

    public Location getLocation() {
        return location;
    }

    public void setLocation(Location location) {
        this.location = location;
    }
}

@Entity(name = "Participant") @Table(name = "participant")
public static class Participant extends BaseEntity {

    @Type(type = "json")
    @Column(columnDefinition = "json")
    private Ticket ticket;

    @ManyToOne
    private Event event;

    public Ticket getTicket() {
        return ticket;
    }

    public void setTicket(Ticket ticket) {
        this.ticket = ticket;
    }

    public Event getEvent() {
        return event;
    }

    public void setEvent(Event event) {
        this.event = event;
    }
}

When inserting the following entities:

final AtomicReference<Event> eventHolder = new AtomicReference<>();
final AtomicReference<Participant> participantHolder = new AtomicReference<>();

doInJPA(entityManager -> {
    Event nullEvent = new Event();
    nullEvent.setId(0L);
    entityManager.persist(nullEvent);

    Location location = new Location();
    location.setCountry("Romania");
    location.setCity("Cluj-Napoca");

    Event event = new Event();
    event.setId(1L);
    event.setLocation(location);
    entityManager.persist(event);

    Ticket ticket = new Ticket();
    ticket.setPrice(12.34d);
    ticket.setRegistrationCode("ABC123");

    Participant participant = new Participant();
    participant.setId(1L);
    participant.setTicket(ticket);
    participant.setEvent(event);

    entityManager.persist(participant);

    eventHolder.set(event);
    participantHolder.set(participant);
});

Hibernate generates the following statements:

INSERT INTO event (location, id) 
VALUES (NULL(OTHER), 0)

INSERT INTO event (location, id) 
VALUES ('{"country":"Romania","city":"Cluj-Napoca"}', 1)

INSERT INTO participant (event_id, ticket, id) 
VALUES (1, {"registrationCode":"ABC123","price":12.34}, 1)

The JSON Object(s) are properly materialized into their associated database columns.

Not only that JSON Object(s) are properly transformed from their database representation:

Event event = entityManager.find(
    Event.class, eventHolder.get().getId());
assertEquals("Cluj-Napoca", event.getLocation().getCity());

Participant participant = entityManager.find(
    Participant.class, participantHolder.get().getId());
assertEquals("ABC123", participant.getTicket().getRegistrationCode());

But we can even issue native JSON-based SQL queries:

List<String> participants = entityManager.createNativeQuery(
    "SELECT p.ticket -> \"$.registrationCode\" " +
    "FROM participant p " +
    "WHERE JSON_EXTRACT(p.ticket, \"$.price\") > 1 ")
.getResultList();

And JSON Object(s) can be modified:

event.getLocation().setCity("Constanța");
entityManager.flush();

Hibernate generating the proper UPDATE statement:

UPDATE event 
SET location = '{"country":"Romania","city":"Constanța"}'
WHERE id = 1

PostgreSQL

PostgreSQL has been supporting JSON types since version 9.2. There are two types that can be used:

  • json
  • jsonb

Both PostgreSQL JSON types need to be materialized using a binary data format, so we need to use the JsonBinaryType this time.

PostgreSQL JSON column type

For the JSON column type, the two JSON Object(s) mapping must be changed as follows:

@Type(type = "jsonb")
@Column(columnDefinition = "json")
private Location location;

@Type(type = "jsonb")
@Column(columnDefinition = "json")
private Ticket ticket;

The insert works just the same, as well as the entity update, and we can even query the JSON column as follows:

List<String> participants = entityManager.createNativeQuery(
    "SELECT p.ticket ->>'registrationCode' " +
    "FROM participant p " +
    "WHERE p.ticket ->> 'price' > '10'")
.getResultList();

PostgreSQL JSONB column type

For the JSONB column type, we only need to change the columnDefinition attribute:

@Type(type = "jsonb")
@Column(columnDefinition = "jsonb")
private Location location;

@Type(type = "jsonb")
@Column(columnDefinition = "jsonb")
private Ticket ticket;

The insert and the JSON Object update work the same, while the JSONB column type provides more advanced querying capabilities:

List<String> participants = entityManager.createNativeQuery(
    "SELECT jsonb_pretty(p.ticket) " +
    "FROM participant p " +
    "WHERE p.ticket ->> 'price' > '10'")
.getResultList();

If you enjoyed this article, I bet you are going to love my book as well.

Conclusion

The generic JSON Types(s) are very useful when you need to map any JSON Object to either a String or a binary database representation.

Code available on GitHub.

If you liked this article, you might want to subscribe to my newsletter too.

Advertisements

48 thoughts on “How to map JSON objects using generic Hibernate Types

    1. Just like you don’t think of how the String or Long Types are implemented when you are writing your entity mappings, most developers will just use a @Type and their JSON mapping will work just fine. You only have to provide this custom Type once.

  1. thats awesome !! thanks for the detailed article. ive always wondered if its possible to use the json field type with hiberante in a nice clean way. i will defenatly try to implement it in my project. on which hibernate version have you tried this ? and are there any breaking changes with hibernate 5 ?

    thanks again for your invested time.

    1. I’m glad you liked it. I used Hibernate 5.1.0 for this example, although I’m sure it works just fine with 5.0.x too.

      I’ve seen many StackOverflow and forum questions regarding migration to Hibernate 5 from 3.x or 4.x, so there’s a lot of knowledge already available on the Internet for this transition. If you use Spring, it’s even easier since they take care of some of those migrations automatically.

  2. Hi Vlad!

    First of all thanks for this great implementation! It does not seem to work with custom key deserializers for map keys though.

    What I want to do is to serialize/deserialize a map into a Postgresql colum with json type.

    The attribute is defined in this way.

    @Column(nullable = false, columnDefinition = "json")
    @Type(type = "jsonb")
    private SortedMap<Matchday, List<TeamPlayer>> teamHistoryAsJson = new TreeMap<>();
    

    Where Matchday class is my class used as key for the map.

    I have added a custom deserializer and then registered a new module of the OBJECT_MAPPER in JacksonUtil.

    public static final ObjectMapper OBJECT_MAPPER = createObjectMapper();

    private static final KeyDeserializer MATCHDAY_KEY_DESERIALIZER = new KeyDeserializer() {
    
        @Override
        public Object deserializeKey(String arg0, DeserializationContext arg1)
                throws IOException, JsonProcessingException {
            return Matchday.valueOf(Integer.parseInt(arg0));
        }
    
    };
    
    private static SimpleModule createSimpleModule() {
        final SimpleModule simpleModule = new SimpleModule("dummy",
                new Version(1, 0, 0, "dummy", "dummy", "dummy"));
        simpleModule.addKeyDeserializer(Matchday.class,
                MATCHDAY_KEY_DESERIALIZER);
        return simpleModule;
    }
    
    private static ObjectMapper createObjectMapper() {
        final ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(createSimpleModule());
        return objectMapper;
    }
    

    However it does seem to be ignored completely and the key is deserialized to String anyway. I know that the typization for generics is lost at the runtime, but maybe there is some way to tell the mapper which types it should use?

  3. What about java.util.Map where the key is of a custom defined type? It seems to get deserialized each an every time to String even if I define and register a module with a custom key deserializer.

  4. We encountered a problem with this solution together with optimistic locking and entity @Version. If the json(b) field is not null, the entity version is getting increased while just loading the entity.

    Any idea or hint to avoid this?
    Do we have to switch to UserType?

      1. It seems to be Sets which are troublesome here. Sets get serialized as Json Arrays and as sets are not ordered (per default), each serialization produced a “new” (especially not equal) Json Array.
        This way I get my entities dirty while only selecting them.

        My solution: Use sorted sets like LinkedHashSet and everything suddenly works again. 😉

  5. Thanks a lot for the post. I tested your solution successfully with hibernate v4.2.21

    Now I’m able to use json as any other type.

  6. Can a JSON Object have a property is a foreign key reference to another JPA entity.

    For example:
    – We have JPA “City” and JSON Location. JSON Location has cityId property that is a foreign key reference to JPA City as below:

    
    @Entity(name = "City")
    @Table(name = "city")
    public class City {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String name;
    
        // getter and setter
    
    }
    
    public class Location implements Serializable {
    
        private String country;
        
        //private String city;
        
        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name = "cityId")
        private City cityId;
    
        // getter and setter
    
    }
    

    City table has 2 records:

    Id – Name
    1 – Cluj-Napoca
    2 – Texas

    Database Location column storing expected:

    {“country”:”Romania”,”cityId”: 1}
    {“country”:”America”,”cityId”: 2}

    I already stored Location successful as above, but when loading JPA “Event” from database, the hibernate does not understand cityId is a foreign key. So, it does not load object City fully.

    I have to load object City from cityId by implement Serializer/Deserializer and it takes a lot of performance.

    Do you have any suggestions?

  7. Love your code, it worked perfectly with Hibernate/JPA.

    However, I can’t manage it to query on JSON level with Postgres (the one that you explained at last in your article). I have this query:

    Query query = JPA.em().createNativeQuery(“SELECT * FROM DocumentAnnotation d WHERE d.annotated_vorinstanz_json ->> ‘instance_court’ = ‘FG München'”);

    And I have data entries in my database in the DocumentAnnotation Table with e.g. this value in my column annotated_vorinstanz_json:

    [{“instance_date”: “2016-02-04”, “instance_type”: “Vorinstanz”, “instance_court”: “FG München”}]

    I wanted to see now the whole data entry based on my query… What is my mistake here?

    Thanks!

    1. Thanks. Related to that native query, I was using PostgreSQL 9.5 and it was working just fine. You should ask the question on the PostgreSQL forum since they surely know better what might be wrong.

  8. Is there a way how to register types for each dialect, or to provide a fallback for databases which do not support JSON? For example it could be stored into NCLOB?
    We have to support numerous databases and cannot afford to change the source code for each of them, yet we want to use JSON when it is available.

    We also use automatic generation of DDL. And for it to generate the table correctly we had to change the getSqlType() to return JAVA_OBJECT instead of OTHER (but OTHER is still used in the binder in JsonBinarySqlTypeDescriptor) since JAVA_OBJECT is registered in PostgreSQL95Dialect:
    this.registerColumnType( Types.JAVA_OBJECT, “json” );

    It seems to me that it could work if the method getSqlType could return either JAVA_OBJECT or NCLOB depending on the dialect. Do you see any way how to achieve this?

    Another options could be to have conditional @TypeDef? In that case there could be multiple definitions of the same name but only one would apply depending on dialect, but that is not possible as far as I know.

    For now, I will just use JsonStringType and use Type.NCLOB.

    1. Yes, you can!

      You can use the annotation-based mapping as the baseline for all DBs supporting JSON, and for the ones that don’t you just override the annotation-based mappings with XML-based configs as explained in this article.

      Cool, right?

  9. Great guide!

    I have problems only with:

    @Type(type = “json”)
    List customList;

    When I try accessing CustomObject I get:
    Request processing failed; nested exception is java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to CustomObject.

    Are List supported?

    1. That’s not supported by this custom type. You need to use a JsonNode which encapsulates the List. Providing a custom List type is much more difficult and only supported via UserCollectionType which will undergo significant changes in 6.0.

    2. I had the similar issue with jsonb type,

      @Type(type = "jsonb")
      private List<NoteEntryData> noteEntries;
      

      When I get the record from jpa repository, this noteEntries becomes List. So I have to tweak JacksonUtil.java, and JsonTypeDescriptor.java.

      Added this method mapJsonToObjectList to JacksonUtil.java. The solution is actually from this answer. http://stackoverflow.com/questions/7040279/jackson-json-java-generics-get-linkedhashmap
      This method will map the generic List back to its true type, rather than List.

      public class JacksonUtil
      {
      ...
          public static  List mapJsonToObjectList(String json, Class clazz)
          {
              List list;
      
          TypeFactory t = TypeFactory.defaultInstance();
          try
          {
              list = objectMapper.readValue(json, t.constructCollectionType(ArrayList.class,clazz));
          } catch (IOException e)
          {
              throw new IllegalArgumentException("The given string value: "
                      + json + " cannot be transformed to List of " + clazz.getName());
          }
      
          return list;
      }
      
      ...
      }
      

      Added JavaXmember to JsonTypeDescriptor class, and use this to check if the jsonb type field is List, and get the Class of the List’s Elelment.

      public class JsonTypeDescriptor
              extends AbstractTypeDescriptor
              implements DynamicParameterizedType
      {
      
      private Class jsonObjectClass;
      private JavaXMember javaXMember;
      
      ...
          @Override
          public Object fromString(String string) {
              if(javaXMember.isCollection())
              {
                  String className = javaXMember.getElementClass().getName();
                  try
                  {
                      return JacksonUtil.mapJsonToObjectList(string, Class.forName(className));
                  } catch (ClassNotFoundException e)
                  {
                      throw new IllegalArgumentException("The given collection of class "
                              + className + " cannot be found.");
                  }
              }
              return JacksonUtil.fromString(string, jsonObjectClass);
          }
      ...
      }
      

      please give me some feedback, thanks.

  10. Hi Vlad, Thank you for the tutorial I am trying to get an understanding of what the MySQL Dialect addition with ‘json’ type in V5.2.10 does ? Is it natively supported now or do I get more features with the latest version ?

    I also posted a question on stackoverflow with more details if you think that will help
    ‘do-i-need-to-upgrade-hibernate-to-5-2-10-to-use-mysql-json-column-effectively’

    1. Just try to implement it with AttributeConverter and see if it works. I bet you are going to need to have much more flexibility at the JDBC PreparedStatement and ResultSet level that you don’t get with standard JPA.

  11. Hi, I got such error with MySQL, do you have some idea?

    Data truncation: Cannot create a JSON value from a string with CHARACTER SET ‘binary’.

  12. Nice post! Why don’t you build a jar file out of the above and make it available in the maven repo so that developers would just have to download it and use it and write something like instead of adding so much code into their code base.?

    JsonTypeObject would be the same as javax.JsonObject.

    @Column(name = “SOME_COLUMN”)
    private org.sth.JsonTypeObject someObject;

  13. Thanks a lot. Building a jar file would help a lot of developers.

    I have another question. Can we write Hibernate Criteria queries while trying to fetch data based on some criterion from JSON instead of using native query as below?

    Currently we are forced to write SELECT statements every time we need to find something from JSON data.

    ‘SELECT ….. WHERE JSON_EXTRACT(p.ticket, \”$.price\”) > 1 “)’

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s