Hydrate entity from external data

I am using debezium in order to do Change Data Capture, and I am looking for a way to use the change data instantiate hibernate managed entities instead of reloading them from db.
Is this possible and how would you go about doing it?

Hibernate internally uses something called an EntityPersister which has all the relational mapping knowledge for an entity. You can use that to create entity instances and set values.

Thanks Christian. I did find that one but after that I was not sure how to continue. Could you give a few more pointers? The only method I can see that could work is:

insert(java.lang.Object[] fields, java.lang.Object object, SharedSessionContractImplementor session);

But where would I get the session for example? I start out with the (@PersistenceUnit) EntityManagerFactory and can get to the EntityPersister by:

entityManagerFactory.unwrap(SessionImpl.class).getMetamodel().entityPersister(Event.class)

Thanks

I don’t understand. Why do you want to use insert? I thought you just want to create the entity objects?

Anyway, the SessionImpl implements the SharedSessionContractImplementor interface.

You can use the EntityPersister#getEntityTuplizer which then can be used to create instances and fill property values.

Not sure what I need to do - I think I need the created entities to be managed by hibernate so that it will still load @OneToMany relations etc when needed. So basically all I want to do is to create a shortcut to load the entity from row data that I got from somewhere else (in my case, debezium/kafka) but after that the entity should behave like any other hibernate managed entity.
Is that still the way to go then?

That’s not so easy. The logic for reading is based on the JDBC ResultSet and starts roughly in org.hibernate.loader.Loader#getRowFromResultSet. So either you try to match what Hibernate does and replace the ResultSet parts with the data from your events, or you try to provide a ResultSet facade over the data and pass that to new EntityLoader( persister, LockMode.NONE, sessionFactory, LoadQueryInfluencers.NONE ).loadSingleRow( resultSet, session, new QueryParameters(), true ), but you might need to mock some context i.e. Session.

I was afraid of that. Do you think it would be better/easier to use the 2nd level cache somehow?

You mean implementing the whole 2nd level cache contract just for this use case? I doubt that would work well, but you never know until you try it. Anyway, I would recommend you wrap the data in a custom ResultSet implementation and either mock the context Session or use a real session, like I proposed.

Ok I’ll go down that path then. Thanks!