I am working with a domain model class which is composed of an embedded object which implements the DomainEvent interface. DomainEvent can be any concrete class and is serialized by Jackson. To solve this in hibernate 5 I have used a CompositeUserType over two columns: event_body, and type_name.
{code:java}public class StoredEvent {
private DomainEvent event; private long eventId; private Instant occurredOn; private String typeName; }{code}
In Hibernate 5 the hbm.xml mapping was very simple and straightforward:
{code:xml}<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-access="field" default-cascade="all"> <class name="event.StoredEvent" table="stored_event" lazy="true"> <id name="eventId" type="long" column="event_id" unsaved-value="-1"> <generator class="identity" /> </id> <property name="event" type="port.adapter.persistence.hibernate.DomainEventUserType"> <column name="event_body"/> <column name="type_name"/> </property> <property name="typeName" column="type_name" insert="false" update="false"/> <property name="occurredOn" column="occurred_on"/> </class> </hibernate-mapping>{code}
The DomainEventUserType was also more or less simple to write:
Testing does work well, and I have provided a reproduced using the test-case-templates on my github: [https://github.com/itsmoonrack/hibernate-test-case-templates|https://github.com/itsmoonrack/hibernate-test-case-templates|smart-link]
In Hibernate 6.0 I did not successfully migrated this composite user type and in fact I tried multiple strategies (implementing the new CompositeUserType) but failed successfully.
I tried the following:
{code:xml}<component name="event" class="port.adapter.persistence.hibernate.DomainEventUserType"> <!-- I was expecting mapping would have been done on the "projection embeddable" --> <property name="eventBody" column="event_body"/> <property name="typeName" column="type_name"/> </component>{code}
but the metamodel mapper is telling me that it “*Could not locate field name [eventBody] on class [domain.model.DomainEvent]*”
I also tried to embbed a component
{code:java}public class StoredEventThatMayWork {
private ComponentMapped event; private long eventId; private Instant occurredOn;
public StoredEventThatMayWork(final DomainEvent event) { this.event = new ComponentMapped(event, event.getClass().getName()); this.occurredOn = event.occurredOn(); }
public static class ComponentMapped {
private DomainEvent eventBody; private String typeName;
public ComponentMapped(final DomainEvent event, final String typeName) { this.eventBody = event; this.typeName = typeName; } } }{code}
but it did not worked either: *Could not determine recommended JdbcType for* {{domain.model.DomainEvent}} |
|