[ https://issues.apache.org/jira/browse/TAP5-2754?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17736751#comment-17736751 ]
Ben Weidig commented on TAP5-2754: ---------------------------------- Further investigation lead me down the road how PropertyShadowBuilder chooses methods to shadow. In the case of interfaces that extend methods with different return types, the duplicate methods must be removed. For example: {code:java} interface Original { Number test(); } interface Extended extends Original { Double test(); } {code} will actually generate two methods in {{{}Extended{}}} as you can see from the bytecode: {code} Classfile /Users/ben/code/tapestry/tapestry-5/Extended.class Last modified 24 Jun 2023; size 254 bytes SHA-256 checksum 708c3793a9074f5afdd523542cf287559d5cbeee871a0ca9757444dc28edafe3 Compiled from "Extended.java" interface Extended extends Original minor version: 0 major version: 61 flags: (0x0600) ACC_INTERFACE, ACC_ABSTRACT this_class: #2 // Extended super_class: #7 // java/lang/Object interfaces: 1, fields: 0, methods: 2, attributes: 1 Constant pool: #1 = InterfaceMethodref #2.#3 // Extended.test:()Ljava/lang/Double; #2 = Class #4 // Extended #3 = NameAndType #5:#6 // test:()Ljava/lang/Double; #4 = Utf8 Extended #5 = Utf8 test #6 = Utf8 ()Ljava/lang/Double; #7 = Class #8 // java/lang/Object #8 = Utf8 java/lang/Object #9 = Class #10 // Original #10 = Utf8 Original #11 = Utf8 ()Ljava/lang/Number; #12 = Utf8 Code #13 = Utf8 LineNumberTable #14 = Utf8 SourceFile #15 = Utf8 Extended.java { public abstract java.lang.Double test(); descriptor: ()Ljava/lang/Double; flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT public default java.lang.Number test(); descriptor: ()Ljava/lang/Number; flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokeinterface #1, 1 // InterfaceMethod test:()Ljava/lang/Double; 6: areturn LineNumberTable: line 1: 0 } SourceFile: "Extended.java" {code} The {{ACC_BRIDGE}} method is used to call the actual method from {{Extended}}. As the {{Method[]}} from a {{Class#getMethods()}} call are neither sorted nor in any particular order, as stated in the javadoc, we sort the methods and remove duplicates by taking the first one. If the return types don't differ, or the changed return type is first, that's fine. In case of {{Session}}, however, the removed method differs if we look at the return type, too. That's why I suspect that even though it should work, as the other method just calls the right one, in the case of a proxy, it doesn't work, as the Proxy does bytecode magic itself. > Some methods of an injected Hibernate Session return null > --------------------------------------------------------- > > Key: TAP5-2754 > URL: https://issues.apache.org/jira/browse/TAP5-2754 > Project: Tapestry 5 > Issue Type: Bug > Components: tapestry-hibernate > Affects Versions: 5.7.2, 5.8.2 > Reporter: Ben Weidig > Assignee: Ben Weidig > Priority: Major > > If you inject the Hibernate Session, some calls might return null. > Identified problematic methods are: > * createNativeQuery > * createQuery > * getNamedQuery > It possible that more methods are affected. > Debugging the issue is complicated, as the Hibernate Session is hidden away > behind a PropertyShadowBuilder. > It's a property on org.apache.tapestry5.hibernate.HibernateSessionManager > that is created in > org.apache.tapestry5.hibernate.modules.HibernateCoreModule.buildSession(HibernateSessionManager, > PropertyShadowBuilder) > The reasoning for this is that the Session doesn't have to be scoped > PerThread, as the HibernateSessionManager is, and the Session is only > actually created on first use, not on HSM creation. > I've debugged through the shadowing process and checked the created > PlasticClass and underlying ClassNode, and they look good to me as all > methods are there. > As everything is runtime-generated bytecode, maybe a tool like > [https://github.com/AdoptOpenJDK/jitwatch] could help to analyze what's > actually happening. > My guess is that the big changes starting Hibernate 5.2 (moving towards > javax.persistence, like Session now extending javax.persistence.EntityManager > and org.hibernate.jpa.HibernateEntityManage) are not 100% compatible with > what Plastic/PropertyShadowBuilder are doing behind the scenes. > It's not completely broken, but certain things seem to work a little > differently. > > *Current workaround:* > Call {{getSession()}} on the injected Session, the method will then work as > intended. > > *Maybe related ticket:* > https://issues.apache.org/jira/browse/TAP5-2582 > > *Related mailing list threads:* > [https://lists.apache.org/thread/r4bhr01d95kpl8pslrhr1bdx486b29nd] > [https://lists.apache.org/thread/qwc6430qq0f4nt7oc755z443c2zh6j68] > > -- This message was sent by Atlassian Jira (v8.20.10#820010)