The first four (of six) sections of code/output below show the normal, expected, “good” case. I have a view, an entity definition, code to find the entity twice and check if it is contained, and the output which shows that it is only retrieved once and is indeed contained.
(The next two sections of code/output show the problem.)
db=> create view backfeedgame as
SELECT a.k AS u_k, gen_random_uuid() AS game_k,
gen_random_uuid() AS shared_game_k,
'foobar' as share_k FROM u a join game b on a.k = b.u_k
group by a.k;
@Immutable
@Entity
class BackfeedGame (
@Id @OneToOne(fetch = FetchType.LAZY) val u: U,
@OneToOne(fetch = FetchType.LAZY) val game: Game,
@OneToOne(fetch = FetchType.LAZY) val shared_game: Game,
@OneToOne(fetch = FetchType.LAZY) val share: Share,
)
val properties = mutableMapOf<String, String>(
).also {
System.getenv("LOCAL")?.apply { it["jakarta.persistence.jdbc.url"] = "jdbc:postgresql:///main" }
}
val em = Persistence.createEntityManagerFactory("ai.prep.wordchase_host", properties).createEntityManager()
val session = em.unwrap(org.hibernate.Session::class.java)
session.beginTransaction()
println("starting")
println("==========")
val u1 = em.find(U::class.java, UUID.fromString("54c614fd-52f6-4000-b7d6-613b56ae1b9b"))
println("Entity u1 managed: ${em.contains(u1)}")
println("..........")
val u2 = em.find(U::class.java, UUID.fromString("54c614fd-52f6-4000-b7d6-613b56ae1b9b"))
println("Entity u2 managed: ${em.contains(u2)}")
println("----------")
val bg1 = em.find(BackfeedGame::class.java, u1.k)
println("First find completed")
println("Entity managed: ${em.contains(bg1)}")
println("..........")
val bg2 = em.find(BackfeedGame::class.java, u2.k)
println("Second find completed")
println("Entity managed: ${em.contains(bg2)}")
println("==========")
session.transaction.commit()
em.close()
System.exit(0)
starting
==========
Hibernate:
select
u1_0.k
from
wordchase_host.U u1_0
where
u1_0.k=?
Entity u1 managed: true
..........
Entity u2 managed: true
----------
Hibernate:
select
bg1_0.u_k,
bg1_0.game_k,
bg1_0.share_k,
bg1_0.shared_game_k
from
wordchase_host.BackfeedGame bg1_0
where
bg1_0.u_k=?
First find completed
Entity managed: true
..........
Second find completed
Entity managed: true
==========
So these are the first four sections of code/showing that all is good.
Now, all I do is merely change the view definition in the database keeping the entity definition the same , and the found entity is not shown as contained
anymore, and a duplicate SQL for the second find
is executed.
db=> create view backfeedgame as
SELECT a.k u_k, gen_random_uuid() AS game_k,
gen_random_uuid() AS shared_game_k,
'foobar' as share_k FROM u a join game b on a.k = b.u_k
JOIN shared c ON b.k = c.game_k
group by a.k;
starting
==========
Hibernate:
select
u1_0.k
from
wordchase_host.U u1_0
where
u1_0.k=?
Entity u1 managed: true
..........
Entity u2 managed: true
----------
Hibernate:
select
bg1_0.u_k,
bg1_0.game_k,
bg1_0.share_k,
bg1_0.shared_game_k
from
wch.BackfeedGame bg1_0
where
bg1_0.u_k=?
Hibernate:
select
bg1_0.u_k,
bg1_0.game_k,
bg1_0.share_k,
bg1_0.shared_game_k
from
wch.BackfeedGame bg1_0
where
bg1_0.u_k=?
First find completed
Entity managed: false
..........
Hibernate:
select
bg1_0.u_k,
bg1_0.game_k,
bg1_0.share_k,
bg1_0.shared_game_k
from
wch.BackfeedGame bg1_0
where
bg1_0.u_k=?
Hibernate:
select
bg1_0.u_k,
bg1_0.game_k,
bg1_0.share_k,
bg1_0.shared_game_k
from
wch.BackfeedGame bg1_0
where
bg1_0.u_k=?
Second find completed
Entity managed: false
==========
This is really weird to me because from hibernate’s perspective the schema of the view is exactly the same so how can hibernate even know whether to do something different in either case.
The first schema below works fine, and the next one triggers the bug.
main=> d+ backfeedgame
View "wch.backfeedgame"
Column | Type | Collation | Nullable | Default | Storage | Description
---------------+------+-----------+----------+---------+----------+-------------
u_k | uuid | | | | plain |
game_k | uuid | | | | plain |
shared_game_k | uuid | | | | plain |
share_k | text | | | | extended |
View definition:
SELECT a.k AS u_k,
gen_random_uuid() AS game_k,
gen_random_uuid() AS shared_game_k,
'foobar'::text AS share_k
FROM u a
JOIN game b ON a.k = b.u_k
GROUP BY a.k;
main=> d+ backfeedgame
View "wch.backfeedgame"
Column | Type | Collation | Nullable | Default | Storage | Description
---------------+------+-----------+----------+---------+----------+-------------
u_k | uuid | | | | plain |
game_k | uuid | | | | plain |
shared_game_k | uuid | | | | plain |
share_k | text | | | | extended |
View definition:
SELECT a.k AS u_k,
gen_random_uuid() AS game_k,
gen_random_uuid() AS shared_game_k,
'foobar'::text AS share_k
FROM u a
JOIN game b ON a.k = b.u_k
JOIN shared c ON b.k = c.game_k
GROUP BY a.k;
Lastly, I have tried both 6.5.2.Final and 6.6.0.CR1 versions of hibernate, and they both show the bug.