✅ Short Answer
In Hibernate, you handle database-specific features (like JSON columns) by:
✅ Using custom types (e.g., UserType
, AttributeConverter
) to map complex or non-standard DB types to Java types.
✅ Leveraging Hibernate dialects that support native functions or types.
✅ (In newer Hibernate versions) Using @JdbcTypeCode
or @JdbcType
to tell Hibernate how to handle vendor-specific SQL types.
🔎 Approach 1: AttributeConverter (simple, single-column)
If your JSON is stored as a single VARCHAR
/TEXT
column, map it to a Java object using @Converter
:
@Converter(autoApply = true)
public class JsonConverter implements AttributeConverter<MyJsonObject, String> {
private final ObjectMapper mapper = new ObjectMapper();
@Override
public String convertToDatabaseColumn(MyJsonObject obj) {
try { return mapper.writeValueAsString(obj); }
catch (JsonProcessingException e) { throw new RuntimeException(e); }
}
@Override
public MyJsonObject convertToEntityAttribute(String json) {
try { return mapper.readValue(json, MyJsonObject.class); }
catch (IOException e) { throw new RuntimeException(e); }
}
}
✅ This lets you declare:
@Entity
public class Document {
@Id
private Long id;
@Column(columnDefinition = "jsonb") // For PostgreSQL JSONB
private MyJsonObject data;
}
🔎 Approach 2: Hibernate UserType (complex or multi-column)
When you need multi-column mapping or full control, implement org.hibernate.usertype.UserType
:
public class JsonUserType implements UserType<MyJsonObject> {
// implement methods like sqlTypes(), nullSafeGet(), nullSafeSet(), etc.
}
✅ Then map your field:
@Type(JsonUserType.class)
private MyJsonObject data;
🔎 Approach 3: Dialect support for vendor-specific features
Hibernate’s Dialects (e.g., PostgreSQLDialect
) define how Hibernate generates SQL for different databases, including support for special types like:
- PostgreSQL:
json
,jsonb
,hstore
,inet
- Oracle:
SDO_GEOMETRY
- MySQL:
JSON
type
Hibernate delegates SQL generation to the dialect, so choosing the right dialect can unlock native DB features.
🔹 Example: PostgreSQL JSON
- PostgreSQLDialect recognizes
jsonb
type. - You can annotate your entity:
@Column(columnDefinition = "jsonb")
private MyJsonObject data;
✅ But you still need an AttributeConverter or UserType to serialize Java ↔ JSON.
🔹 Hibernate 6+ approach with @JdbcTypeCode
Hibernate 6 introduced @JdbcTypeCode
for easier mapping of custom SQL types:
@Entity
public class Document {
@JdbcTypeCode(SqlTypes.JSON)
@Column(columnDefinition = "jsonb")
private MyJsonObject data;
}
✅ Hibernate 6 automatically uses Jackson (if on classpath) to serialize/deserialize JSON → minimal boilerplate.
🔹 Calling vendor-specific SQL functions
You can call DB-native JSON functions via JPQL or native queries:
List<Object[]> result = em.createNativeQuery(
"SELECT id, data->>'key' FROM document").getResultList();
📌 Key Takeaways
✅ For database-specific features like JSON, map them using AttributeConverter
, UserType
, or Hibernate 6’s @JdbcTypeCode
.
✅ Choose the right Hibernate dialect → it determines SQL syntax and native type support.
✅ Leverage native SQL or JPQL if you need advanced DB-specific functions.