I want to write a query like SELECT * FROM Release_date_type a LEFT JOIN cache_media b on a.id=b.id
. I am new to Spring Data JPA. I don't know how to write entities for Join query. Here is an attempt:
@Entity @Table(name = "Release_date_type") public class ReleaseDateType { @Id @GeneratedValue(strategy=GenerationType.TABLE) private Integer release_date_type_id; // ... @Column(nullable = true) private Integer media_Id; // with getters and setters... }
Another entity is:
@Entity @Table(name = "Cache_Media") public class CacheMedia { @Id @GeneratedValue(strategy=GenerationType.TABLE) private Integer id; // ... private Date loadDate; //with the getter and setter .. }
I want to write a crudRepository
interface such as
public interface ReleaseDateTypeRepository extends CrudRepository<ReleaseDateType, Long>{ @Query("SELECT * FROM Release_date_type a LEFT JOIN cache_media b on a.id=b.id") public List<ReleaseDateType> FindAllWithDescriptionQuery(); }
Here is an attempt: @Entity @Table(name = "Release_date_type") public class ReleaseDateType { @Id @GeneratedValue(strategy=GenerationType. TABLE) private Integer release_date_type_id; // ... @Column(nullable = true) private Integer media_Id; // with getters and setters... }
The only way to join two unrelated entities with JPA 2.1 and Hibernate versions older than 5.1, is to create a cross join and reduce the cartesian product in the WHERE statement. This is harder to read and does not support outer joins. Hibernate 5.1 introduced explicit joins on unrelated entities.
Joining Tables with JPA Specifications select author0_.id as id1_1_, author0_. first_name as first_na2_1_, author0_. last_name as last_nam3_1_ from author author0_ inner join author_books books1_ on author0_.id = books1_. author_id inner join book book2_ on books1_.
For a typical example of employees owning one or more phones, see this wikibook section.
For your specific example, if you want to do a one-to-one
relationship, you should change the next code in ReleaseDateType model:
@Column(nullable = true) private Integer media_Id;
for:
@OneToOne(fetch = FetchType.LAZY) @JoinColumn(name="CACHE_MEDIA_ID", nullable=true) private CacheMedia cacheMedia ;
and in CacheMedia model you need to add:
@OneToOne(cascade=ALL, mappedBy="ReleaseDateType") private ReleaseDateType releaseDateType;
then in your repository you should replace:
@Query("Select * from A a left join B b on a.id=b.id") public List<ReleaseDateType> FindAllWithDescriptionQuery();
by:
//In this case a query annotation is not need since spring constructs the query from the method name public List<ReleaseDateType> findByCacheMedia_Id(Integer id);
or by:
@Query("FROM ReleaseDateType AS rdt WHERE cm.rdt.cacheMedia.id = ?1") //This is using a named query method public List<ReleaseDateType> FindAllWithDescriptionQuery(Integer id);
Or if you prefer to do a @OneToMany
and @ManyToOne
relation, you should change the next code in ReleaseDateType model:
@Column(nullable = true) private Integer media_Id;
for:
@OneToMany(cascade=ALL, mappedBy="ReleaseDateType") private List<CacheMedia> cacheMedias ;
and in CacheMedia model you need to add:
@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name="RELEASE_DATE_TYPE_ID", nullable=true) private ReleaseDateType releaseDateType;
then in your repository you should replace:
@Query("Select * from A a left join B b on a.id=b.id") public List<ReleaseDateType> FindAllWithDescriptionQuery();
by:
//In this case a query annotation is not need since spring constructs the query from the method name public List<ReleaseDateType> findByCacheMedias_Id(Integer id);
or by:
@Query("FROM ReleaseDateType AS rdt LEFT JOIN rdt.cacheMedias AS cm WHERE cm.id = ?1") //This is using a named query method public List<ReleaseDateType> FindAllWithDescriptionQuery(Integer id);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With