Skip to content
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

Lazy one-to-one with Bytecode enhancement enabled doesn't work #1417

Closed
DavideD opened this issue Nov 2, 2022 · 2 comments · Fixed by #1418
Closed

Lazy one-to-one with Bytecode enhancement enabled doesn't work #1417

DavideD opened this issue Nov 2, 2022 · 2 comments · Fixed by #1418
Assignees
Labels
bug Something isn't working
Milestone

Comments

@DavideD
Copy link
Member

DavideD commented Nov 2, 2022

See quarkusio/quarkus#28975

Example:

@Entity
public class Leader {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	Long id;

	String name;

	@OneToOne(fetch = FetchType.LAZY, mappedBy = "leader", cascade = CascadeType.ALL)
	Follower follower;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Follower getFollower() {
		return follower;
	}

	public void setFollower(Follower follower) {
		this.follower = follower;
	}

	@Override
	public String toString() {
		return id + ":" + name;
	}
}


@Entity
public class Follower {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	public Long id;

	public String name;

	@OneToOne(fetch = FetchType.LAZY)
	public Leader leader;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Leader getLeader() {
		return leader;
	}

	public void setLeader(Leader leader) {
		this.leader = leader;
	}

	@Override
	public String toString() {
		return id + ":" + name;
	}

Test for MutinyMain in examples:


		Leader leader = new Leader();
		leader.name = "The One Who Waits";

		Follower follower = new Follower();
		follower.name = "Lamb";

		leader.follower = follower;
		follower.leader = leader;

		try {
			factory.withTransaction(
					// persist the Authors with their Books in a transaction
					(session, tx) -> session.persistAll( leader, follower )
			).chain( () -> factory
					.withSession( session -> session
							.find( Leader.class, leader.id )
							.chain( l -> Mutiny.fetch( l.getFollower() ) )
							.invoke( f -> out.println( f ) )
					)
			).await().indefinitely();
		}
		finally {
			// remember to shut down the factory
			factory.close();
		}

Error:

Exception in thread "main" org.hibernate.PropertyAccessException: Could not set field value [java.util.concurrent.CompletableFuture@3bab286c[Not completed]] value by reflection : [class org.hibernate.reactive.example.session.Leader.follower] setter of org.hibernate.reactive.example.session.Leader.follower
	at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:72)
	at org.hibernate.property.access.spi.EnhancedSetterImpl.set(EnhancedSetterImpl.java:41)
	at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValue(AbstractEntityTuplizer.java:688)
	at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValue(AbstractEntityPersister.java:5256)
	at org.hibernate.persister.entity.AbstractEntityPersister.initializeLazyProperty(AbstractEntityPersister.java:1380)
	at org.hibernate.reactive.persister.entity.impl.ReactiveSingleTableEntityPersister.initializeLazyProperty(ReactiveSingleTableEntityPersister.java:321)
	at org.hibernate.reactive.persister.entity.impl.ReactiveAbstractEntityPersister.initLazyProperty(ReactiveAbstractEntityPersister.java:1292)
	at org.hibernate.reactive.persister.entity.impl.ReactiveAbstractEntityPersister.reactiveInitializeLazyPropertiesFromDatastore(ReactiveAbstractEntityPersister.java:1238)
	at org.hibernate.reactive.persister.entity.impl.ReactiveSingleTableEntityPersister.initializeLazyPropertiesFromDatastore(ReactiveSingleTableEntityPersister.java:328)
	at org.hibernate.reactive.persister.entity.impl.ReactiveSingleTableEntityPersister.initializeLazyPropertiesFromDatastore(ReactiveSingleTableEntityPersister.java:42)
	at org.hibernate.persister.entity.AbstractEntityPersister.initializeLazyProperty(AbstractEntityPersister.java:1198)
	at org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor.lambda$loadAttribute$0(LazyAttributeLoadingInterceptor.java:108)
	at org.hibernate.bytecode.enhance.spi.interceptor.EnhancementHelper.performWork(EnhancementHelper.java:206)
	at org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor.loadAttribute(LazyAttributeLoadingInterceptor.java:80)
	at org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor.fetchAttribute(LazyAttributeLoadingInterceptor.java:76)
	at org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor.handleRead(LazyAttributeLoadingInterceptor.java:57)
	at org.hibernate.bytecode.enhance.spi.interceptor.AbstractInterceptor.readObject(AbstractInterceptor.java:153)
	at org.hibernate.reactive.example.session.Leader.$$_hibernate_read_follower(Leader.java)
	at org.hibernate.reactive.example.session.Leader.getFollower(Leader.java:45)
	at org.hibernate.reactive.example.session.MutinyMain.lambda$main$1(MutinyMain.java:65)
	at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.performInnerSubscription(UniOnItemTransformToUni.java:68)
	at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.onItem(UniOnItemTransformToUni.java:57)
	at io.smallrye.mutiny.operators.uni.UniOperatorProcessor.onItem(UniOperatorProcessor.java:46)
	at io.smallrye.mutiny.operators.uni.builders.UniCreateFromCompletionStage$CompletionStageUniSubscription.forwardResult(UniCreateFromCompletionStage.java:63)
	at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:859)
	at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:837)
	at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
	at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2073)
	at io.vertx.core.Future.lambda$toCompletionStage$3(Future.java:384)
	at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
	at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
	at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
	at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23)
	at io.vertx.sqlclient.impl.QueryResultBuilder.tryComplete(QueryResultBuilder.java:100)
	at io.vertx.sqlclient.impl.QueryResultBuilder.tryComplete(QueryResultBuilder.java:34)
	at io.vertx.core.Promise.complete(Promise.java:66)
	at io.vertx.core.Promise.handle(Promise.java:51)
	at io.vertx.core.Promise.handle(Promise.java:29)
	at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
	at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:54)
	at io.vertx.core.impl.EventLoopContext.execute(EventLoopContext.java:86)
	at io.vertx.core.impl.DuplicatedContext.execute(DuplicatedContext.java:163)
	at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:51)
	at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
	at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23)
	at io.vertx.core.impl.future.PromiseImpl.onSuccess(PromiseImpl.java:49)
	at io.vertx.core.impl.future.PromiseImpl.handle(PromiseImpl.java:41)
	at io.vertx.core.impl.future.PromiseImpl.handle(PromiseImpl.java:23)
	at io.vertx.sqlclient.impl.command.CommandResponse.fire(CommandResponse.java:46)
	at io.vertx.sqlclient.impl.SocketConnectionBase.handleMessage(SocketConnectionBase.java:287)
	at io.vertx.pgclient.impl.PgSocketConnection.handleMessage(PgSocketConnection.java:97)
	at io.vertx.sqlclient.impl.SocketConnectionBase.lambda$init$0(SocketConnectionBase.java:100)
	at io.vertx.core.impl.EventLoopContext.emit(EventLoopContext.java:55)
	at io.vertx.core.impl.ContextBase.emit(ContextBase.java:239)
	at io.vertx.core.net.impl.NetSocketImpl.handleMessage(NetSocketImpl.java:390)
	at io.vertx.core.net.impl.ConnectionBase.read(ConnectionBase.java:157)
	at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:153)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
	at io.vertx.pgclient.impl.codec.PgEncoder.lambda$write$0(PgEncoder.java:98)
	at io.vertx.pgclient.impl.codec.PgCommandCodec.handleReadyForQuery(PgCommandCodec.java:139)
	at io.vertx.pgclient.impl.codec.PgDecoder.decodeReadyForQuery(PgDecoder.java:237)
	at io.vertx.pgclient.impl.codec.PgDecoder.channelRead(PgDecoder.java:96)
	at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.IllegalArgumentException: Can not set org.hibernate.reactive.example.session.Follower field org.hibernate.reactive.example.session.Leader.follower to java.util.concurrent.CompletableFuture
	at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
	at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
	at java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
	at java.base/java.lang.reflect.Field.set(Field.java:780)
	at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:52)
	... 81 more

> Task :session-example:MutinyMain.main() FAILED

We should also move these tests in the module integration-tests.

@DavideD DavideD added the bug Something isn't working label Nov 2, 2022
@DavideD DavideD added this to the next milestone Nov 2, 2022
@DavideD DavideD self-assigned this Nov 2, 2022
DavideD added a commit to DavideD/hibernate-reactive that referenced this issue Nov 3, 2022
@DavideD
Copy link
Member Author

DavideD commented Nov 3, 2022

I've started to have a look at this issue, but something is still not working.
During the delete there is an unexpected CompletionStage.

I will have to get back to it later.
This is the progress so far, if somebody wants to have a look: https://github.com/DavideD/hibernate-reactive/pull/new/1417-lazy-one-to-one

But I don't know if it works as definitive fix.

I've created a new module so that I could enable the bytecode enhancements.

@DavideD DavideD removed their assignment Nov 3, 2022
@DavideD
Copy link
Member Author

DavideD commented Nov 4, 2022

I think I have a fix. I will send a PR in a bit

@DavideD DavideD self-assigned this Nov 4, 2022
DavideD added a commit to DavideD/hibernate-reactive that referenced this issue Nov 4, 2022
When using Bytecode Enhancements with a lazy bidirectional one-to-one,
we have an error because we rerturn a CompletionStage instead of
using the fetched object.

This commit should fix the issue.
DavideD added a commit to DavideD/hibernate-reactive that referenced this issue Nov 4, 2022
Additional module for testing using Hibenrate ORM Bytecode Enhancements
The module uses the Hibernate Gradle plugin to enable the features.

This is not an elegant solution and there is some duplicated code from
the core module, but it beats not being able to test these use cases.
DavideD added a commit to DavideD/hibernate-reactive that referenced this issue Nov 4, 2022
DavideD added a commit to DavideD/hibernate-reactive that referenced this issue Nov 4, 2022
When using Bytecode Enhancements with a lazy bidirectional one-to-one,
we have an error because we rerturn a CompletionStage instead of
using the fetched object.

This commit should fix the issue.
DavideD added a commit to DavideD/hibernate-reactive that referenced this issue Nov 4, 2022
Additional module for testing using Hibenrate ORM Bytecode Enhancements
The module uses the Hibernate Gradle plugin to enable the features.

This is not an elegant solution and there is some duplicated code from
the core module, but it beats not being able to test these use cases.
DavideD added a commit to DavideD/hibernate-reactive that referenced this issue Nov 4, 2022
DavideD added a commit to DavideD/hibernate-reactive that referenced this issue Nov 4, 2022
When using Bytecode Enhancements with a lazy bidirectional one-to-one,
we have an error because we rerturn a CompletionStage instead of
using the fetched object.

This commit should fix the issue.
DavideD added a commit to DavideD/hibernate-reactive that referenced this issue Nov 4, 2022
Additional module for testing using Hibenrate ORM Bytecode Enhancements
The module uses the Hibernate Gradle plugin to enable the features.

This is not an elegant solution and there is some duplicated code from
the core module, but it beats not being able to test these use cases.
DavideD added a commit to DavideD/hibernate-reactive that referenced this issue Nov 5, 2022
DavideD added a commit to DavideD/hibernate-reactive that referenced this issue Nov 5, 2022
When using Bytecode Enhancements with a lazy bidirectional one-to-one,
we have an error because we rerturn a CompletionStage instead of
using the fetched object.

This commit should fix the issue.
DavideD added a commit to DavideD/hibernate-reactive that referenced this issue Nov 5, 2022
Additional module for testing using Hibenrate ORM Bytecode Enhancements
The module uses the Hibernate Gradle plugin to enable the features.

This is not an elegant solution and there is some duplicated code from
the core module, but it beats not being able to test these use cases.
DavideD added a commit that referenced this issue Nov 5, 2022
DavideD added a commit that referenced this issue Nov 5, 2022
When using Bytecode Enhancements with a lazy bidirectional one-to-one,
we have an error because we rerturn a CompletionStage instead of
using the fetched object.

This commit should fix the issue.
DavideD added a commit that referenced this issue Nov 5, 2022
Additional module for testing using Hibenrate ORM Bytecode Enhancements
The module uses the Hibernate Gradle plugin to enable the features.

This is not an elegant solution and there is some duplicated code from
the core module, but it beats not being able to test these use cases.
@DavideD DavideD modified the milestones: next, 2.0.0.Alpha1 Mar 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant