I am trying to use a ...ContainingIgnoreCase JPA query to extract the information from three related objects: profile (id), profile_interest (profile_id and interest_id) and interests (id).
In my service I call
@Service public class SearchService {
@Autowired
private ProfileDao profileDao;
public List<SearchResult> search(String text) {
return profileDao.findByInterestsNameContainingIgnoreCase(text).stream().map(SearchResult::new).collect(Collectors.toList());
}
}
Then my DAO executes it:
Blockquote @Repository public interface ProfileDao extends CrudRepository {
Profile findByUsuario(Usuario usuario);
List<Profile> findByInterestsNameContainingIgnoreCase(String text);
}
My Profile Object:
package music.bolo.domain.entity;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.OrderColumn;
import javax.persistence.Table;
import org.owasp.html.PolicyFactory;
import music.bolo.domain.dto.FileInfo;
@Entity
@Table(name = "profile")
public class Profile {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private long id;
@OneToOne(targetEntity = Usuario.class)
@JoinColumn(name = "user_id", nullable = false)
private Usuario usuario;
@Column(name = "about", length = 5000)
private String about;
@Column(name = "photo_directory", length = 10)
private String photoDirectory;
@Column(name = "photo_name", length = 10)
private String photoName;
@Column(name = "phot_extension", length = 5)
private String photoExtension;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "profile_interests", joinColumns = { @JoinColumn(name = "profile_id") }, inverseJoinColumns = {
@JoinColumn(name = "interest_id") })
@OrderColumn(name = "display_order")
private Set<Interest> interests;
public Profile() {
}
public Profile(Usuario usuario) {
this.usuario = usuario;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Usuario getUsuario() {
return usuario;
}
public void setUsuario(Usuario usuario) {
this.usuario = usuario;
}
public String getAbout() {
return about;
}
public void setAbout(String about) {
this.about = about;
}
public String getPhotoDirectory() {
return photoDirectory;
}
public void setPhotoDirectory(String photoDirectory) {
this.photoDirectory = photoDirectory;
}
public String getPhotoName() {
return photoName;
}
public void setPhotoName(String photoName) {
this.photoName = photoName;
}
public String getPhotoExtension() {
return photoExtension;
}
public void setPhotoExtension(String photoExtension) {
this.photoExtension = photoExtension;
}
// Create a profile that is suitable for displaying via JSP
public void safeCopyFrom(Profile other) {
if (other.about != null) {
this.about = other.about;
}
if (other.interests != null) {
this.interests = other.interests;
}
}
// Create a profile sanitized for saving
public void safeMergeFrom(Profile webProfile, PolicyFactory htmlPolicy) {
if (webProfile.about != null) {
this.about = htmlPolicy.sanitize(webProfile.about);
}
}
public void setPhotoDetails(FileInfo info) {
photoDirectory = info.getSubDirectory();
photoExtension = info.getExtension();
photoName = info.getBasename();
}
public Path getPhoto(String baseDirectory) {
if (photoName == null) {
return null;
}
return Paths.get(baseDirectory, photoDirectory, photoName + "." + photoExtension);
}
public Set<Interest> getInterests() {
return interests;
}
public void setInterests(Set<Interest> interests) {
this.interests = interests;
}
public void addInterest(Interest interest) {
interests.add(interest);
}
public void removeInterest(String interestName) {
interests.remove(new Interest(interestName));
}
@Override
public String toString() {
return "Profile [id=" + id + ", usuario=" + usuario + ", about=" + about + ", photoDirectory=" + photoDirectory
+ ", photoName=" + photoName + ", photoExtension=" + photoExtension + ", interests=" + interests + "]";
}
}
But... I get this error
2017-01-24 22:06:38.357 INFO 4656 --- [ restartedMain] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' 2017-01-24 22:06:38.389 INFO 4656 --- [ restartedMain] o.apache.catalina.core.StandardService : Stopping service Tomcat 2017-01-24 22:06:38.404 WARN 4656 --- [ost-startStop-1] o.a.c.loader.WebappClassLoaderBase : The web application [ROOT] appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread: java.lang.Object.wait(Native Method) java.lang.ref.ReferenceQueue.remove(Unknown Source) com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:43) 2017-01-24 22:06:38.420 ERROR 4656 --- [ restartedMain] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'indexController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private music.bolo.services.ProfileService music.bolo.controllers.IndexController.profileService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'profileService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: music.bolo.domain.repository.ProfileDao music.bolo.services.ProfileService.profileDao; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'profileDao': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Illegal attempt to dereference path source [null.interests] of basic type at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]