spring-projects / spring-framework

Spring Framework
https://spring.io/projects/spring-framework
Apache License 2.0
56.15k stars 37.95k forks source link

Hibernate Search Bytecode Enhancement Issue #33255

Closed aiden-sim closed 1 month ago

aiden-sim commented 1 month ago

I reported the following issue to the Hibernate team: https://hibernate.atlassian.net/browse/HSEARCH-5205

org.hibernate.engine.spi.EnhancedEntity.isAssignableFrom(Parent.class) is false (Parent wasn't enhanced)
org.hibernate.engine.spi.EnhancedEntity.isAssignableFrom(Child.class) is true (was enhanced).

The response I received was that this is an issue that occurs before Hibernate ORM is initialized.

Here is the address of my personal repository that reproduces the issue, and I hope it will be fixed if it is a bug. Please check it out https://github.com/aiden-sim/hibernate-search-bytecode-issue

bclozel commented 1 month ago

@aiden-sim no need to create duplicates issues. This one was moved here on purpose.

snicoll commented 1 month ago

@aiden-sim why is Parent annotated with @Configurable? That doesn't make much sense for an entity to me.

aiden-sim commented 1 month ago

@snicoll Thank you for your response.

@Entity
@NoArgsConstructor
@Getter
@Setter
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type")
@Table(name = "sample")
@Configurable
@Indexed
public abstract class Parent extends DomainBase<Long> {
    @Column(nullable = false, length = 50)
    @NotNull
    @GenericField(projectable = Projectable.YES, sortable = Sortable.YES, searchable = Searchable.YES)
    private String name;

    @Transient
    @JsonIgnore
    @Autowired
    @Expose(serialize = false, deserialize = false)
    protected transient ParentDetailService parentDetailService;

    public ParentDetail getParentDetails() {
        return parentDetailService.getParentDetail(getId());
    }

}

Currently, in the Parent class, we are using AspectJ with LoadTimeWeaving to directly call services like ParentDetailService. This is a piece of legacy code that has been carried forward to the present.

Regarding the part that I have reported, is it a bug, or are we using it improperly?

snicoll commented 1 month ago

Thanks for the feedback.

Regarding the part that I have reported, is it a bug, or are we using it improperly?

Using LTW with an entity the way you do is strongly discouraged as it can be quite fragile as we see here. It's not obvious to us why this used to work, but both Hibernate and Spring trying to enhance the same class is a recipe for trouble.

Please move that code outside of the entity. If you really can't, it would be nice to get some additional details such as if the order between the Hibernate enhancer and the Configurable aspect changed between the two versions.

aiden-sim commented 1 month ago

@snicoll

removing @Configurable doesn't change the situation. Instead, if I remove spring-instrument-6.1.10.jar at the LoadTimeWeaving stage, it works. I suspect that there is a conflict occurring when using Hibernate Search and spring-instrument together. Is there anything else I can check?

snicoll commented 1 month ago

removing @Configurable doesn't change the situation.

What's left that requires LTW then?

aiden-sim commented 1 month ago

removing @Configurable doesn't change the situation.

What's left that requires LTW then?

@snicoll We are also using LTW (Load-Time Weaving) to address transaction self-invocation issues...

snicoll commented 1 month ago

I mean in the example that you’ve shared.

aiden-sim commented 1 month ago

@snicoll Using @Configurable in the domain does not seem to be related to the issue. Instead, while using Hibernate Search functionality with @Indexed in the domain and spring-instrument library for LTW, we are encountering bytecode conflicts.

Our team has decided to remove the LTW approach for now. I hope you share it if resolved later. Thanks.