简体   繁体   中英

How can i use a mysql query to get an entity and multiple entities that relate to it?

So i have 3 tables: tutorials, topics, and tutorial_topics (maps the many to many relation). I have this query:

select
            t.id,
            t.created,
            t.created_by,
            t.last_modified,
            t.last_modified_by,
            t.version,
            l.name,
            l.description,
            top
        from
            tutorials t
        inner join
            localized_tutorial l
        inner join topics as top
        where l.name like '%Fish Cooking%' and l.locale='pt';

Now first, it tells me that t.id does not exist (i assume because is a derived table doesnt recognize the t.id from parent query), if i remove t.id verifications, says that topics in the first select is an unknown column, and if i put the join instead of the select (like below) just says i cant return a column with multiple objects. Im trying to send this to a spring boot app that receives this data. Is there any way to fix it?

select
            t.id,
            t.created,
            t.created_by,
            t.last_modified,
            t.last_modified_by,
            t.version,
            l.name,
            l.description,
            (select * from topics topic inner join topics_tutorials ttopic where topic.id = ttopic.topics_id and t.id = ttopic.tutorials_id)
        from
            tutorials t
        inner join
            localized_tutorial l
        where l.name like '%Java%' and l.locale='pt';

This is my tutorial table:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Table(name = SQL.TUTORIAL_TABLE)
@Entity(name = SQL.TUTORIAL_ENTITY)
@ToString(doNotUseGetters = true, callSuper = true)
@EqualsAndHashCode(doNotUseGetters = true, callSuper = true)
public class TutorialDAO implements Serializable {

    @Id
    @GeneratedValue(generator = "uuid2", strategy = GenerationType.AUTO)
    @Column(columnDefinition = "BINARY(16)", unique = true)
    @GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
    private UUID id;

    @CreatedDate
    private LocalDateTime created;

    @CreatedBy
    private String createdBy;

    @LastModifiedDate
    private LocalDateTime lastModified;

    @LastModifiedBy
    private String lastModifiedBy;

    @Version
    private int version;

    private static final long serialVersionUID = -1697137782136090241L;

    private boolean exclusive;

    @ToString.Exclude
    @EqualsAndHashCode.Exclude
    @ManyToMany(mappedBy = "tutorials", cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
    private Set<TopicDAO> topics = new HashSet<>();

    @ToString.Exclude
    @EqualsAndHashCode.Exclude
    @ElementCollection(fetch = FetchType.EAGER)
    private Set<SectionDAO> sections = new HashSet<>();

    @ToString.Exclude
    @EqualsAndHashCode.Exclude
    @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    @JoinTable(name = "tutorial_courses", joinColumns = @JoinColumn(name = "tutorial_id"), inverseJoinColumns = @JoinColumn(name = "course_id"))
    private Set<CourseDAO> courses = new HashSet<>();

    @ToString.Exclude
    @EqualsAndHashCode.Exclude
    @OneToMany(mappedBy = "tutorial", cascade = { CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,
            CascadeType.REFRESH }, orphanRemoval = true, fetch = FetchType.LAZY)
    @MapKey(name = "localizedId.locale")
    private Map<String, LocalizableTutorial> localizations = new HashMap<>();
}

And this is my Projection class

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString(doNotUseGetters = true, callSuper = true)
@EqualsAndHashCode(doNotUseGetters = true, callSuper = true)
public class LocalizedTutorialDAO extends AbstractDAO {

    private static final long serialVersionUID = -8671921365618993655L;

    private String name, description;

    @ToString.Exclude
    @EqualsAndHashCode.Exclude
    private Set<TopicDAO> topics = new HashSet<>();

    @ToString.Exclude
    @EqualsAndHashCode.Exclude
    private Set<SectionDAO> sections = new HashSet<>();
}

The topic entity is just an id and a topic string. i made it an entity in order to avoid duplicates. My question is: from a tutorialDAO object how can i get a LocalizedTutorialDAO? i already can retrieve name and description from its localizations with the query:

select new com.fullstack.daos.projections.LocalizedTutorialDAO(t.id, t.created, t.createdBy, t.lastModified, t.lastModifiedBy, t.version, (VALUE(l)).name, (VALUE(l)).description) from tutorial t join t.localizations l where (VALUE(l)).name like %:name% and (KEY(l)) = :lang

The thing is when i need topics, it just gives the problems i described. However a spring generated FindById return the whole tutorial with topics, if i try to replicate it tho, nothing happens

From your queries, I think you want to select all columns from table topics but able to do it. Below is the method you can use to fetch them -

select t.id,
       t.created,
       t.created_by,
       t.last_modified,
       t.last_modified_by,
       t.version,
       l.name,
       l.description,
       top.[1st_col_topics_table],
       top.[2nd_col_topics_table],
       top.[3rd_col_topics_table],
       top.[4th_col_topics_table]
       ...
  from tutorials t
 inner join localized_tutorial l on <join condition>
 inner join topics_tutorials ttopic on t.id = ttopic.tutorials_id
 inner join topics top on top.id = ttopic.topics_id
 where l.name like '%Fish Cooking%' and l.locale='pt';

You cannot just write the table alias to fetch all columns. You have to mention all the columns explicitly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM