View Javadoc
1   /*
2    *  Copyright 2014 Christopher Pheby
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package org.jadira.usertype.json.jackson;
17  
18  import java.io.IOException;
19  import java.lang.reflect.InvocationTargetException;
20  import java.sql.PreparedStatement;
21  import java.sql.ResultSet;
22  import java.sql.SQLException;
23  import java.sql.Types;
24  
25  import org.hibernate.HibernateException;
26  import org.hibernate.engine.spi.SharedSessionContractImplementor;
27  import org.postgresql.util.PGobject;
28  
29  import com.fasterxml.jackson.core.JsonParseException;
30  import com.fasterxml.jackson.core.JsonProcessingException;
31  import com.fasterxml.jackson.databind.JsonMappingException;
32  
33  public class PersistentJsonObjectAsPostgreSQLJson<T> extends PersistentJsonObjectAsString<T> {
34  
35  	private static final long serialVersionUID = 228945479215593795L;
36  
37  	private static boolean HAS_POSTGRES_DRIVER;
38  	
39  	static {
40  		
41  		try {
42  		Class.forName("org.postgresql.util.PGobject");
43  		HAS_POSTGRES_DRIVER = true;
44  		} catch (ClassNotFoundException e) {
45  			HAS_POSTGRES_DRIVER = false;
46  		}
47  	}
48  	
49      @Override
50      public Object doNullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
51  
52          Object identifier = rs.getObject(names[0]);
53          
54          if (rs.wasNull()) {
55              return null;
56          }
57  
58  		final String jsonText;
59  		if (HAS_POSTGRES_DRIVER && identifier instanceof PGobject) {
60              PGobject pg = (PGobject) identifier;
61              jsonText = pg.getValue();
62          } else if (identifier instanceof String) { // some PostgreSQL Dialects / Versions return String not PGObject
63              jsonText = (String)identifier;
64          } else {
65              throw new IllegalArgumentException("PersistentJsonObjectAsPostgreSQLJson type expected PGobject, received " + identifier.getClass().getName() + " with value of '" + identifier + "'");
66          }
67  		
68  		try {
69  			Object obj = getObjectReader().readValue(jsonText);
70  			return obj;			
71  		} catch (JsonParseException e) {
72  			throw new HibernateException("Problem parsing retrieved JSON String: " + jsonText, e);
73  		} catch (JsonMappingException e) {
74  			throw new HibernateException("Problem mapping retrieved JSON String: " + jsonText, e);
75  		} catch (IOException e) {
76  			throw new HibernateException("Problem reading JSON String: " + jsonText, e);
77  		}
78      }
79  
80      @Override
81      public void doNullSafeSet(PreparedStatement preparedStatement, Object value, int index, SharedSessionContractImplementor session) throws SQLException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
82  
83      	if (value == null) {
84  			preparedStatement.setNull(index, Types.NULL);
85  		} else {				
86  			
87  			try {
88  				String identifier = getObjectWriter().writeValueAsString(value);
89  				
90  				Object jsonObject;
91  				if (HAS_POSTGRES_DRIVER) {
92  				
93  		        	PGobject pgObject = new PGobject();
94  		        	pgObject.setType("json");
95  		        	pgObject.setValue(identifier);
96  		        	jsonObject = pgObject;
97  				} else {
98  					jsonObject = identifier;
99  				}
100 				
101 	            preparedStatement.setObject(index, jsonObject);
102 			} catch (JsonProcessingException e) {
103 				throw new HibernateException("Problem writing JSON String: " + e.getMessage(), e);
104 			}
105 		}
106     }
107 }