spring-data-relational icon indicating copy to clipboard operation
spring-data-relational copied to clipboard

Storing non root entities in serialized form [DATAJDBC-450]

Open spring-projects-issues opened this issue 5 years ago • 4 comments
trafficstars

Bahadır Yağan opened DATAJDBC-450 and commented

It may be a good feature to optionally store non-root entities in a single column in the aggregate root's table, rather than separate table(s)

Object tree will be serialized (possibly as json) and stored in a single text column. The user than has the option of using their DBMS' support for such columns. (jsonb or hstore for postgres is an example)

My somewhat related SO question:

https://stackoverflow.com/questions/58910098/mapstring-string-single-column-mapping-in-spring-data-jdbc

 

 


Issue Links:

  • DATAJDBC-476 BasicRelationalConverter.writeValue(…) assumes eager entity conversion

  • DATACMNS-1036 Add API for property specific converters

spring-projects-issues avatar Nov 28 '19 11:11 spring-projects-issues

Mihhail Verhovtsov commented

I had a similar use-case where I wanted to support Postgres's JSONB columns. I didn't want to use a wrapper for my collections as its makes data access more cumbersome. Additionaly, I am not convinced that type-based converters are a good option either in terms of flexibility (BTW, do they properly support generics?). I wanted to achieve something like this:

@Data
public class Company {

    private @Id Long id;
    private String name;

    @JSONB
    private List<Representative> representatives = new ArrayList<>();

}

This gives me the freedom to customize serialization mechanism of particular properties. I envisioned that @JSONB could use meta-annotations that somehow told what it's converter type was.

The first problem was that Spring Data JDBC treated collections and maps as entity collections. I extended JdbcMappingContext and introduced an extended version of BasicJdbcPersistentProperty, which additionally checks for @Simple annotation on the property to determine whether the property should be treated as a simple type or not. If I am not mistaken, this solves the problem stated in DATAJDBC-476.

This way I got into BasicJdbcConverter's methods readValue(..) and writeValue(..). However, this is where it stopped. This converter does not have access to the property itself and therefore cannot examine the annotations of the property.

Naturally, I tried going up one level and override that behaviour of DefaultDataAccessStrategy, which calls JdbcConverter. Unfortunately, the methods of interest like addConvertedPropertyValue(..) are all private. Overriding them would mean re-implementing data access strategy from the ground. Clearly, this is not a future-proof approach.

What are your thoughts on this? Maybe I am not seeing a simpler way already supported by Spring Data JDBC? I would love to devote my time supporting this use case

spring-projects-issues avatar Apr 16 '20 11:04 spring-projects-issues

Jens Schauder commented

I think there are a couple of different things that we should try to keep separate.

1.  adding conversions for properties (not based on the type of the property). We probably want to build on some yet to be created infrastructure in Commons. See DATACMNS-1036 

2. We might need more than just the conversion itself, but also a way to generate SQL snippets for writing and reading.  For example MySql seems to need a CAST in order to write JSON to the database. https://dev.mysql.com/doc/refman/8.0/en/json.html#json-values

If anyone wants to tackle this they should probably start with a simple implementation for this issue, together with creating the necessary infrastructure for  DATACMNS-1036 

 

spring-projects-issues avatar Apr 16 '20 12:04 spring-projects-issues

This would be really great addition to Spring Data JDBC. It would be then a perfect fit for DDD. Clean aggregates that are stored in single RDBMS row within tables that can be indexed by root aggregate attributes, but also to some degree on child entity attributes (depending on a RDBMS)

mcekovic avatar Sep 29 '21 21:09 mcekovic