0

検索クエリに問題があります。

私のモデル:

計画:

@Entity
@Table(name = "project")
public class Project {

    @Id
    @Column(name = "id")
    @GeneratedValue
    private Integer id;

    @ManyToMany(fetch=FetchType.EAGER)
    @JoinTable(
        name="project_tag",
        joinColumns = @JoinColumn(name="project_id"),
        inverseJoinColumns = @JoinColumn(name="tag_id")
    )
    private Set<Tag> requiredSkills;

    @Column(name="name")
    private String name;

    @Column(name = "short_description", columnDefinition="TEXT")
    private String shortdescription;

    @Column(name = "extended_description", columnDefinition="TEXT")
    private String extendedDescription;
}

鬼ごっこ:

@Entity
@Table(name="tag", uniqueConstraints = {@UniqueConstraint(columnNames={"name"})})
public class Tag {

    @Id
    @Column(name = "id")
    @GeneratedValue
    private Integer id;

    @Column(name = "name")
    private String name;

    public int hashCode() {
        return getName().hashCode();
    }
}

いくつかの検索文字列を使用してプロジェクトを検索したいのですが、この文字列が名前、短い説明、詳細な説明、AND タグに含まれているプロジェクトを見つけたいと考えています。タグの検索が問題です。

これが私のクエリです:

public List<Project> search(String search) {
        search = "%" + search + "%";
        Query query = sessionFactory.getCurrentSession().createQuery(
                "from Project p" +
                " left join fetch p.requiredSkills r" +
                " where p.name like :search" +
                " or p.shortdescription like :search" +
                " or p.extendedDescription like :search" +
                " or r.name like :search"
                );
        query.setParameter("search", search);

        query.setMaxResults(30);

        return (List<Project>) query.list();
    }

「またはr.name like :search」という行でエラーが発生します(それがなくてもすべて正常に動作します):

java.lang.NullPointerException
    myProject.model.Tag.hashCode(Tag.java:53)

このエラーは、いくつかのプロジェクトが見つかった場合にのみ発生します (結果が返されない場合はエラーになりません)。何か案は?ありがとう!

編集: プロジェクトには 0 から n 個のタグがある可能性があることを忘れていました...

4

2 に答える 2

1

コードと例外を考えると、これは名前のないタグがあることを意味しますgetName().hashCode()。NullPointerExceptionをスローするため、getName()nullを返します。

とはいえ、タグの部分的なリストを含むプロジェクトが返されるため、クエリは危険なものです。クエリを次のように書き直す必要があります

select p from Project p
left join fetch p.requiredSkills r
where p.name like :search
or p.shortdescription like :search
or p.extendedDescription like :search
or (exists(select r2.id from Project p2 
           inner join p2.requiredSkills r2
           where p2.id = p.id and r2.name like :search))
于 2012-01-17T17:20:31.847 に答える
0

そこで、JB Nizet が提案したクエリから「fetch」キーワードを削除したところ、うまくいきました...

最終クエリ:

Query query = sessionFactory.getCurrentSession().createQuery(
            "select distinct p" +
            " from Project p" +
            " left join p.requiredSkills r" +
            " where p.name like :search" +
            " or p.shortdescription like :search" +
            " or p.extendedDescription like :search" +
            " or exists(select r2 from Project p2 join p2.requiredSkills r2 where p2.id = p.id and r2.name like :search)");

この問題は修正されないというhttps://community.jboss.org/wiki/HibernateFAQ-AdvancedProblems#I_have_a_nonlazy_set_of_entities_that_override_equals_and_Hibernate_throws_a_NullPointerExceptionに関連している可能性があります...

編集:フェッチで再試行しましたが、うまくいきました...理由がわかりません!

于 2012-01-17T18:51:38.827 に答える