Lazy loading attributes
Hibernate can load attribute lazily, but you need to enable byte code enhancements:
First you need to set the property hibernate.enhancer.enableLazyInitialization
to true
Then you can annotate the field with @Basic( fetch = FetchType.LAZY )
.
Here's the example from the documentation:
@Entity
public class Customer {
@Id
private Integer id;
private String name;
@Basic( fetch = FetchType.LAZY )
private UUID accountsPayableXrefId;
@Lob
@Basic( fetch = FetchType.LAZY )
@LazyGroup( "lobs" )
private Blob image;
//Getters and setters are omitted for brevity
}
You can also enable this feature via the Hibernate ORM gradle plugin
Named Native queries
You could also decide to not map it and save/read it with a named native query. It seems a good trade off for a single attribute - it will just require an additional query to save the json.
Example:
@Entity
@Table(name = "MyEntity_table")
@NamedNativeQuery(
name = "write_json",
query = "update MyEntity_table set json_column = :json where id = :id")
@NamedNativeQuery(
name = "read_json",
query = "select json_column from MyEntity_table where id = :id")
class MyEntity {
....
}
Long id = ...
String jsonString = ...
session.createNamedQuery( "write_json" )
.setParameter( "id", id )
.setParameter( "json", jsonString )
.executeUpdate();
jsonString = (String)session.createNamedQuery( "read_json" )
.setParameter( "id", id )
.getSingleResult();
In this case, schema generation is not going to create the column, so you will need to add it manually (not a big deal, considering that there are better tools to update the schema in production).
MappedSuperclass
You can also have two entities extending the same superclass (this way you don't have to copy the attributes). They have to update the same table:
@MappedSuperclass
class MyEntity {
@Id
Long id;
String name
...
}
@Entity
@Table(name = "MyEntity_table")
class MyEntityWriter extends MyEntity {
String json
}
@Entity
@Table(name = "MyEntity_table")
class MyEntityReader extends MyEntity {
// No field is necessary here
}
Now you can use MyEntityWriter
for saving all the values and MyEntityReader
for loading only the values you need.
I think you will have some problems with schema generation if you try to create the tables because only one of the two will be created:
- If
MyEntityWriter
is the first table created, then no problem
- If
MyEntityWriter
is the second table created, the query will fail because the table already exist and the additional column won't be created.
I haven't tested this solution though, there might be something I haven't thought about.