Home > database >  JPA get foreign key without loading related record
JPA get foreign key without loading related record

Time:04-12

I am trying to optomize some reports and am trying to remove the need to load some expensive related records(multiple cascade loads, on each of ~500 records).

My entity's are something like this:

@Entity
@Table(name="foo")
public class Foo
{
    @Id
    @Type(type = "pg-uuid")
    private UUID id;
...
    public UUID getId(){
        return id;
    }

and:

@Entity
@Table(name="bar")
public class Bar
{
    @Id
    @Type(type = "pg-uuid")
    private UUID id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="FOO_ID")
    private Foo foo;
...

    public UUID getFooId(){
        return foo.getId();
    }

My issue is that when i make this call: return foo.getId(); hibernate goes and instantiates the Foo entity, and loads all related records even though i only want/need the id, which is a foreign key in my Bar table.

Is there any way to get Foo.Id from Bar without loading the Foo record? Thanks in advance.

CodePudding user response:

Try mapping the FOO_ID column as a basic mapping instead or in addition to the existing Foo reference mapping:

@Entity
@Table(name="bar")
public class Bar
{
    @Id
    @Type(type = "pg-uuid")
    private UUID id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="FOO_ID")
    private Foo foo;

    @Column(name="FOO_ID", insertable=false, updatable=false)
    private UUID fooId;
...

    public UUID getFooId(){
        return fooId;
    }

You can then decide to use fooId in queries to avoid joins. Because it is read-only, the FK value is still set from the foo reference - there may be some issues with a cache if you set the reference and not the fooId UUID; you can either set it yourself, or force a refresh to have JPA do it for you.

CodePudding user response:

Hibernate thinks that getFooId() is a method that can potentially use any field of Bar. Hibernate can't check which fields exactly are used by the method, so it loads all lazy associations just in case.

You can use @Transient to avoid this

@Transient
public UUID getFooId(){
    return foo.getId();
}
  • Related