Question

I have an issue with a search query.

My model:

Project:

@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;
}

Tag:

@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();
    }
}

I want to search projects with some search string, and I want to find projects with this string in the name, short description, extended description, AND tags. Searching for tags is the problem.

Here is my query:

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();
    }

The line "or r.name like :search" is giving me an error (everything works fine without it):

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

I get this error only when some projects are found (no error when no results returned). Any ideas? Thanks!

Edit: forgot to tell that projects may have 0 to n tags...

Was it helpful?

Solution 2

So, I just deleted the "fetch" keyword from JB Nizet's proposed query, and it worked...

Final query:

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)");

Might be related to https://community.jboss.org/wiki/HibernateFAQ-AdvancedProblems#I_have_a_nonlazy_set_of_entities_that_override_equals_and_Hibernate_throws_a_NullPointerException saying that this problem will not be corrected...

Edit: tried again with fetch, it worked... Don't understand why!

OTHER TIPS

Given the code and the exception, this means that you have a tag without name: getName().hashCode() throws a NullPointerException, so getName() returns null.

That said, your query is a dangerous one, because it returns projects with a partial list of their tags. You should rewrite the query as

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))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top