spring-bootjpajoinspring-data-jpa

JPA join with the entity transient field


I have a Entity with a Entity @Transient field, when I run a query I have an error.

The query has a join with the entity transient field

@Entity
@Table(name = "OTHER")
public class OtherEntity implements Serializable {
    @Id
    private Long id
   
    @Column( name = "code" )
    private String code;
}

@Entity
@Table(name = "MARKER")
public class MarkerEntity implements Serializable {
    @Id
    private Long id
    
    @Column(name = "OTHER_FIELD")
    private Long otherId;

    @Transient
    private OtherEntity other;

    public MarkerEntity(Long otherId, OtherEntity other) {
        this.otherId = otherId;
        this.other = other;
    }
}

and this is the jpa query

@Query("SELECT " +
  "new MarkerEntity(" +
  "  o.id, " +
  "  new OtherEntity(o.id, o.code)" +
  ") m " +
  "JOIN OtherEntity o")
public List<MarkerEntity> entities(@Param("id") Long id)

Solution

  • When you attempt to join OtherEntity with the transient other field in MarkerEntity, JPA throws an error because it doesn't know how to handle this transient association Instead of using a @Transient field, you can define a relationship between MarkerEntity and OtherEntity using @ManyToOne. This allows JPA to handle the join naturally without needing a transient field.

    @Entity @Table(name = "OTHER") 
    public class OtherEntity implements Serializable { 
      @Id private Long id; 
      @Column(name = "code") private String code; 
    
      // Add a default constructor for JPA 
      public OtherEntity() {} 
    
      public OtherEntity(Long id, String code) { 
        this.id = id; 
        this.code = code;
      }
    
      // Getters and Setters
    }
    
    @Entity 
    @Table(name = "MARKER") 
    public class MarkerEntity implements Serializable { 
      @Id private Long id; 
      @Column(name = "OTHER_FIELD", insertable = false, updatable = false) 
      private Long otherId; 
    
      @ManyToOne @JoinColumn(name = "OTHER_FIELD", referencedColumnName = "id") 
      private OtherEntity other; 
    
      public MarkerEntity() {} 
      public MarkerEntity(Long otherId, OtherEntity other) {
        this.otherId = otherId; 
        this.other = other; 
      } 
    
      // Getters and Setters 
    } 
    

    With this relationship set up, your query can be simplified as follows

    @Query("SELECT new MarkerEntity(m.other.id, m.other) FROM MarkerEntity m WHERE enter code herem.id = :id") 
    public List entities(@Param("id") Long id);