# Title: Inconsistent Proxy Behavior with Kotlin Property Access and Custom Method

**URL:** <https://discourse.hibernate.org/t/title-inconsistent-proxy-behavior-with-kotlin-property-access-and-custom-method/10746>\
**Category:** Hibernate ORM\
**Created:** [December 6, 2024, 4:23am UTC](https://discourse.hibernate.org/t/title-inconsistent-proxy-behavior-with-kotlin-property-access-and-custom-method/10746 "2024-12-06T04:23:25Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![tmdgusya](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/tmdgusya/32/3670_2.png) [@tmdgusya](https://discourse.hibernate.org/u/tmdgusya)\
**Post date:** [December 6, 2024, 4:23am UTC](https://discourse.hibernate.org/t/title-inconsistent-proxy-behavior-with-kotlin-property-access-and-custom-method/10746/1 "2024-12-06T04:23:25Z")

</div>

Description:

I am experiencing inconsistent behavior with Hibernate proxies when accessing a Kotlin property that has a custom getter method with the same name but a different return type.

Steps to Reproduce:

```kt
@Entity
class AdGroup(
	@Id
	...

	@Column
	var adProcutId: Long? = null
) {
	
	fun getAdProductId(): Long = requiredNotNull(this.adProcutId)
}

```

- Create a Kotlin entity class with a property named adProductId of type Long? (nullable).
- Define a custom getter method named getAdProductId() in the entity class, which returns Long.  
Access the adProductId property using adGroup.adProductId.  
Expected Behavior:

Hibernate proxy should intercept the property access and call the long-returning getAdProductId() method.

Actual Behavior:

The behavior is inconsistent across different deployments.

In some deployments, the proxy correctly intercepts the property access and calls the long-returning getAdProductId() method.  
In other deployments, the proxy bypasses the interceptor and directly accesses the adProductId field, resulting in a null value.

```kt
// Debug Output Examples
// Case 1: When it fails (adProductId is null but getAdProductId() returns 3)
println("${adGroup.adProductId} || ${adGroup.getAdProductId()}") 
// Output: null || 3

// Case 2: When it succeeds (both return 3, no code changes, only redeployed)
println("${adGroup.adProductId} || ${adGroup.getAdProductId()}") 
// Output: 3 || 3

```

Analysis:

The issue seems to be related to the order of methods in the publicMethods array of the entity class’s reflection data.  
When the long-returning getAdProductId() method appears before the Long-returning (Kotlin-generated getter) getAdProductId() method in the publicMethods array, the proxy behaves correctly.  
When the Long-returning getAdProductId() method appears first, the proxy bypasses the interceptor and accesses the field directly.

**debug data when it succeed**

```auto
persistentClass = class org.xx.xx.AdGroup

42 = {Method@27931} "public long org.xx.xx.getAdProductId()"
 methodAccessor = {DelegatingMethodAccessorImpl@27995} 
   method = {Method@27931} "public long org.xx.xx.getAdProductId()"
  delegate = {NativeMethodAccessorImpl@27998} 

43 = {Method@27932} "public java.lang.Long org.xx.xx.getAdProductId()"
 methodAccessor = null
 name = "getAdProductId"
 returnType = {Class@499} "class java.lang.Long"\

```

**debug data when it failed**

```debug
46 = {Method@27714} "public java.lang.Long org.xx.xx.getAdProductId()"
 methodAccessor = {DelegatingMethodAccessorImpl@27773} 
  delegate = {NativeMethodAccessorImpl@27777} 
   method = {Method@27714} "public java.lang.Long org.xx.xx.getAdProductId()"

47 = {Method@27715} "public long org.xx.xx.getAdProductId()"
 methodAccessor = null

```

Solution (I found it):

Rename the custom getter method to avoid name conflict with the Kotlin property getter.

Add the @Transient annotation to the Long-returning getAdProductId() method.

Java Version: JDK 11  
Kotlin version: org.jetbrains.kotlin:kotlin-stdlib-jdk8  
Hibernate version: 5.6.15.Final

Request:

Please investigate this issue. It would be helpful to understand why the proxy behavior is affected by the method order in the publicMethods array and whether there is a more reliable way to ensure consistent proxy behavior.

---

<div class="post-metadata">

**Author:** ![tmdgusya](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/tmdgusya/32/3670_2.png) [@tmdgusya](https://discourse.hibernate.org/u/tmdgusya)\
**Post date:** [December 9, 2024, 5:00am UTC](https://discourse.hibernate.org/t/title-inconsistent-proxy-behavior-with-kotlin-property-access-and-custom-method/10746/2 "2024-12-09T05:00:58Z")

</div>

For my investigation, I think reasons that this inconsistent error happen are from allowing to creating function with same name, but different returning signature like the below code.

```kotlin
fun getAdProductId(): java.lang.Long {

}

fun getAdProductId(): long {

}

```

So, I was trying to type same code with Java. But, Java didn’t allow to type these code. The errors came from java was “‘getAdProductId()’ clashes with ‘getAdProductId()’; both methods have same erasure”. Thus, this problem can cause this inconsistent proxy behavior.

The below response is from [kotlin-lang slack channel](https://kotlinlang.slack.com/archives/C7L3JB43G/p1733510504069849?thread_ts=1733499134.876969&cid=C7L3JB43G).

```auto
This is not a platform declaration clash because these declarations are technically not clashing from the Kotlin's point of view.
There's a request at KT-23913 to improve behavior in such cases though. Personally I believe it could be a warning or an error in this special "Java API" mode.
YouTrackYouTrack
Add compilation mode for Java API developers : KT-23913
When it's enabled warnings should be reported whenever resulting API becomes problematic for usage from Java (while being fine in Kotlin) See related issues for examples

```

---

<div class="post-metadata">

**Author:** ![mbladel](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/mbladel/32/2128_2.png) [@mbladel](https://discourse.hibernate.org/u/mbladel)\
**Post date:** [December 11, 2024, 8:58am UTC](https://discourse.hibernate.org/t/title-inconsistent-proxy-behavior-with-kotlin-property-access-and-custom-method/10746/3 "2024-12-11T08:58:53Z")

</div>

@tmdgusya this already looks like an edge-case on the Kotlin side, and I would certainly discourage having properties with multiple getter methods on Hibernate entities in the first place. We can help you if you can demonstrate a problem that occurs with a simple Java application, but keep in mind that property accessor methods for entities in the JPA specification **must** follow the [Java Beans conventions](https://jakarta.ee/specifications/persistence/3.1/jakarta-persistence-spec-3.1.html#persistent-fields-and-properties), and while Hibernate tries to be more lax about this requirement it’s still [heavily encouraged](https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#entity-pojo-accessors).
