-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support hibernate-enhance-maven-plugin
plugin
#148
Comments
This sounds useful! I don't have time or personal itch to work on this but I hope someone has -- and I will be happy to help improvement(s) merged in once ready, and to help with Jackson side aspects (I am not very Hibernaty savvy). |
@cowtowncoder I looked at the source code of this project. Then I found out It didn't use Hibernate's provided |
I can create PR. But I need to understand how Jackson works. |
I just created a maven profile to test with |
@hurelhuyag I did not write this extension module and never used Hibernate so unfortunately I do not know the logic. If I had to guess, I'd suggest that perhaps this method was not available in some (earlier) versions of Hibernate. |
After days of digging. I found a fairly simple solution. Unfortunately, This solution can't be applied by Module. @JsonFilter("lazyPropertyFilter")
public interface LazyPropertyFilterMixin {}
@Bean
Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return builder -> builder
.mixIn(ManagedEntity.class, LazyPropertyFilterMixin.class)
.mixIn(HibernateProxy.class, LazyPropertyFilterMixin.class)
.filters(new SimpleFilterProvider(Map.of("lazyPropertyFilter", new LazyPropertyFilter())));
} |
Modules can actually do such registration (although with bit of casting). But requirement to overwrite One possibility would be to add a separate helper module to be registered along with main module. Or helper class. One request: could you include |
My Latest LazyPropertyFilter implementation: public class LazyPropertyFilter implements PropertyFilter {
@Override
public void serializeAsField(Object pojo, JsonGenerator gen, SerializerProvider prov, PropertyWriter writer) throws Exception {
var initialized = isPropertyInitialized((BeanPropertyWriter) writer, pojo);
if (initialized) {
writer.serializeAsField(pojo, gen, prov);
} else if (!gen.canOmitFields()) { // since 2.3
writer.serializeAsOmittedField(pojo, gen, prov);
}
}
@Override
public void serializeAsElement(Object elementValue, JsonGenerator gen, SerializerProvider prov, PropertyWriter writer) {
throw new RuntimeException("LazyPropertyFilter.serializeAsElement() currently unsupported");
}
@SuppressWarnings("deprecation")
@Override
public void depositSchemaProperty(PropertyWriter writer, ObjectNode propertiesNode, SerializerProvider provider) throws JsonMappingException {
writer.depositSchemaProperty(propertiesNode, provider);
}
@Override
public void depositSchemaProperty(PropertyWriter writer, JsonObjectFormatVisitor objectVisitor, SerializerProvider provider) throws JsonMappingException {
writer.depositSchemaProperty(objectVisitor, provider);
}
public static boolean isPropertyInitialized(BeanPropertyWriter prop, Object bean) throws Exception {
return Hibernate.isPropertyInitialized(bean, prop.getName())
&& isInitialized(prop, bean, ManyToOne.class, ManyToOne::fetch)
&& isInitialized(prop, bean, ElementCollection.class, ElementCollection::fetch)
&& isInitialized(prop, bean, OneToMany.class, OneToMany::fetch)
&& isInitialized(prop, bean, Basic.class, Basic::fetch);
}
public static <A extends Annotation> boolean isInitialized(
BeanPropertyWriter prop, Object bean, Class<A> type, Function<A, FetchType> fetch) throws Exception {
var ann = prop.getAnnotation(type);
if (ann == null) {
return true;
}
var fetchType = fetch.apply(ann);
if (fetchType == FetchType.EAGER) {
return true;
}
var value = prop.get(bean);
return Hibernate.isInitialized(value);
}
} |
Compile-time class enhancement has advantages. When we use it hibernate does not need to create new classes at runtime. But this module is not working with the
hibernate-enhance-maven-plugin
. Because this enhancer plugin adds proxy to getters and Jackson serializer calls getter before detecting property state. We should find a way to detect property that is lazily loaded before invoking the getter method.I have created a minimal project for demonstrating this behaviour.
https://github.com/hurelhuyag/demo-jackson-hibernate5-mininal
The text was updated successfully, but these errors were encountered: