Skip to main content

Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » NamedEntityGraph hint does not use table joins(NamedEntityGraph hint does not use table joins)
NamedEntityGraph hint does not use table joins [message #1828104] Mon, 01 June 2020 19:58 Go to next message
Peter Coppens is currently offline Peter CoppensFriend
Messages: 1
Registered: June 2020
Junior Member

I am struggling to get my head around the idea/usage/behaviour of NamedEntityGraph

Bottom line is I am trying to have EclipseLink generate 1 SQL with a join between two tables

Code fragments looks like so (Kotlin)

            name = "user"
            name = "user-role-properties",
            attributeNodes = [
                NamedAttributeNode("name") ,
                NamedAttributeNode("userRoles", subgraph = "roleproperties"),
                NamedAttributeNode("userProperties", subgraph = "propertiesproperties")],
            subgraphs = [
                NamedSubgraph (name ="roleproperties", attributeNodes = [NamedAttributeNode("roleType")]),
                NamedSubgraph (name ="propertiesproperties", attributeNodes = [NamedAttributeNode("properties")])
            name = "user-role",
            attributeNodes = [
                NamedAttributeNode("name") ,
                NamedAttributeNode("userRoles", subgraph = "roleproperties")] ,
            subgraphs = [
                NamedSubgraph (name="roleproperties", attributeNodes = [NamedAttributeNode("roleType")])]
            name = "user-properties",
            attributeNodes = [
                NamedAttributeNode("name") ,
                NamedAttributeNode("userProperties", subgraph = "propertiesproperties2")
            subgraphs = [
                javax.persistence.NamedSubgraph(name = "propertiesproperties2", attributeNodes = [javax.persistence.NamedAttributeNode("properties")])

@Table(name = "public.user")
open class UserEntity(
        @Id  @Column(name="ID") var id: UUID?,
        @Column (name="lock_version") var lockVersion: Int = 0,
        var name: String?,
        var state: String?,
        var email: String?,
        @Column (name="created_at") var createdAt: Timestamp?,
        @Column (name="updated_at") var updatedAt: Timestamp?,
        @Column (name="email_verified_at") var emailVerifiedAt: Timestamp?,
        @Column (name="last_graph_downloaded_at") var lastGraphDownloadedAt: Timestamp?,
        @OneToMany(fetch= FetchType.LAZY) @JoinColumn(name="user_id")
        var userRoles: Set<UserRoleEntity>,
        @OneToOne(fetch= FetchType.LAZY, optional = true ) @JoinColumn(name="id", insertable=false, updatable=false)
        var userProperties: UserPropertiesEntity?

@Table(name = "user_role")
open class UserRoleEntity(
        var id: UUID?,
        var user_id: UUID?,
        var roleType: String?

@Table(name = "user_properties")
open class UserPropertiesEntity(
        @Id @Column(name="user_id")
        val userId: UUID?,
        @Column(name="updated_by") var updatedBy: UUID?,
        @Column(name="updated_at") var updatedAt: Timestamp?,
        @Column(name="properties") var properties: String?


val graph =    entityManager.getEntityGraph("user-properties")
val properties: MutableMap<String, Any> = HashMap()
properties["javax.persistence.fetchgraph"] = graph
val ue =  entityManager.find(, UUID.fromString(id), properties)

Static weaving seems successful

Running this code results in 4 SQL's

SELECT ID, NAME FROM public.user WHERE (ID = ?)
SELECT user_id, properties FROM user_properties WHERE (user_id = ?)
SELECT user_id, properties, updated_at, updated_by FROM user_properties WHERE (user_id = ?)
SELECT ID, created_at, EMAIL, email_verified_at, last_graph_downloaded_at, lock_version, NAME, STATE, updated_at FROM public.user WHERE (ID = ?)

If I do not set the NamedEntityGraph property I am only getting 2 SQL's (4th and 3rd)

So ideally, I want one SQL joining user and user_properties table

Anyone any tips?

Certainly appreciated!

Re: NamedEntityGraph hint does not use table joins [message #1828207 is a reply to message #1828104] Wed, 03 June 2020 23:50 Go to previous message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 1388
Registered: July 2009
Senior Member
EntityGraph is a fetch graph, telling what needs to be all pre-fetched and loaded , but doesn't specify 'how' to fetch things- that is completely left up to the mappings. If you want joining so it is all done in a single query, you'd need to specify fetch join/batching query hints, or add fetch join and BatchFetch annotations to your model. Without additional settings, you can't get it all read in with a single query.

As for getting the 4 queries when using your named graph: your named graph is defining properties, which explains the 1st and 2nd SQL statements. The remaining 3rd and 4th would get caused when touching anything unfetched in the returned object graph, as JPA treats them all as lazy, and accessing them forces fetching the entire object. Your code is likely triggering something on both these objects, forcing the additional SQL to be issued.

To prove it is your code and not some internal mechanism of EclipseLink triggering the 3rd and 4th statement, the easiest way I can think of is to remove one of the missing columns from the DB (I use views over my tables and just rename the table back when done). This will cause an exception, and the stack will show exactly where the 3rd (or 4th) statement is being issued from. If it is from the em.find call somehow, we'd need the stack trace to help narrow down why.
Previous Topic:JPA 2.1 AttributeConverter autoApply option not working if converter class extends base class
Next Topic:ElementCollection List<String> Exception during deployment
Goto Forum:

Current Time: Fri Jun 25 11:18:18 GMT 2021

Powered by FUDForum. Page generated in 0.01644 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top