JPA- Joining two tables in non-entity class

后端 未结 3 1101
情书的邮戳
情书的邮戳 2020-12-08 01:16

I am a newbie ,tried to google but I am unable to solve my query. Please help.

I am trying to map two entities : PersonA and Person in my POJO class PersonC

3条回答
  •  天涯浪人
    2020-12-08 01:49

    This post deals with the Hibernate.

    The suggestion of putting the @SqlResultSetMapping and @NamedNativeQuery (or @NamedQuery) inside the @Entity class definition is not elegant and evidently does not follow the separation of concerns principle.

    The more proper solution is the usage of the @MappedSuperclass annotation as the following:

    SingerExtended.java (the class must be abstract):

    package pl.music.model.singer.extended;
    
    import javax.persistence.ColumnResult;
    import javax.persistence.ConstructorResult;
    import javax.persistence.MappedSuperclass;
    import javax.persistence.NamedNativeQueries;
    import javax.persistence.NamedNativeQuery;
    import javax.persistence.SqlResultSetMapping;
    
    @MappedSuperclass
    @SqlResultSetMapping( // @formatter:off
        name = "SingerExtendedMapping",
        classes = @ConstructorResult(
            targetClass = SingerExtendedDTO.class,
            columns = {
                @ColumnResult(name = "singer_id", type = Long.class),
                @ColumnResult(name = "first_name"),
                @ColumnResult(name = "last_name"),
                @ColumnResult(name = "count_albums", type = Long.class)
            }
        )
    )
    @NamedNativeQueries({
        @NamedNativeQuery(
                name = "SingerExtendedAsc",
                query = "select"
                    + " singer.singer_id,"
                    + " singer.first_name,"
                    + " singer.last_name,"
                    + " (select count(*) from album where album.singer_id = singer.singer_id) as count_albums"
                    + " from singer"
                    + " group by singer.singer_id"
                    + " order by last_name collate :collation asc, first_name collate :collation asc",
                resultSetMapping = "SingerExtendedMapping"
        )
    }) // @formatter:on
    public abstract class SingerExtended {
    }
    

    then DAO class SingerExtendedDAO.java:

    package pl.music.model.singer.extended;
    
    import java.util.List;
    
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    import javax.persistence.TypedQuery;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    @Component
    public class SingerExtendedDAO {
    
        @PersistenceContext
        EntityManager entityManager;
    
        @Autowired
        private String collation;
    
        public List getAll(Integer page, Integer count) {
            TypedQuery query = entityManager.createNamedQuery("SingerExtendedAsc", SingerExtendedDTO.class);
            query.setParameter("collation", collation);
            if ((count != null) && (count.intValue() > 0)) {
                query.setMaxResults(count.intValue());
                if ((page != null) && (page.intValue() >= 0)) {
                    query.setFirstResult(count.intValue() * page.intValue());
                }
            }
            List singerExtendedDTOs = query.getResultList();
            return singerExtendedDTOs;
        }
    
    }
    

    and finally the DTO class SingerExtendedDTO.java (you must provide "full" constructor):

    package pl.music.model.singer.extended;
    
    public class SingerExtendedDTO {
    
        private Long singerId;
        private String firstName;
        private String lastName;
        private Long countAlbums;
    
        // IMPORTANT: this constructor must be defined !!! 
        public SingerExtendedDTO(Long singerId, String firstName, String lastName, Long countAlbums) {
            this.singerId = singerId;
            this.firstName = firstName;
            this.lastName = lastName;
            this.countAlbums = countAlbums;
        }
        ... getters & setters ...
    }
    

    If all this is put together the way presented above, we obtain a proper solution:

    • everything is in one package,
    • query declaration does not pollute any unconcerned entity,
    • separation of concerns is preserved (seperated query+mapping, DAO and DTO).

提交回复
热议问题