Let's take a following entity:
class Item{
@Id
Long id;
String name;
org.joda.money.Money price;
}
and a corresponding repository:
interface ItemRepository extends CrudRepository<Item, Long> {
}
Is it possible to persist Item in a relational DB table having amount and currency in separate columns without manually rewriting SQL queries offered by ItemRepository
?
DDL could be something like:
CREATE TABLE ITEM (
ID INTEGER IDENTITY NOT NULL,
NAME VARCHAR(255) NULL,
PRICE_AMOUNT DECIMAL NULL,
PRICE_CURRENCY VARCHAR(3) NULL
);
Storing Money in a single VARCHAR
column using custom @WritingConverter
and @ReadingConverter
is the closest I got, however this is not an option, as I need amount and currency clearly separated at the DB level.
I'm fine with replacing joda.money
in favor of javax.money
if that makes a difference, however I do not want to introduce my own custom type for handling money in domain layer.
There are the following options available to persist properties of non standard types in Spring Data JDBC
Use @WritingConverter
and @ReadingConverter
in order to convert the value to something Spring Data JDBC knows. You already discovered that this works only with single columns
You can mark it as an @Embedded
which will convert each attribute to a column. I'm not sure if Money
has suitable attributes but it is lacking a suitable constructor so this doesn't work either.
Use a different type that you can handle with one of the first approaches. In this case this would mean write your own Money
type which has a suitable constructor and attributes to work as an embedded.
Tweak your database: you can create a view which uses a single column representation and stores it as a single column. It might still make it available as separate columns for sorting and filtering.