I'm developing a simple register system that allow users to register. I have the following configuration, entity and service:
persistence.xml
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="pro-jpa" transaction-type="JTA">
<jta-data-source>jdbc/__testPerso</jta-data-source>
<class>com.jules.esiee.entities.Utilisateur</class>
<properties>
<property name="eclipselink.ddl-generation" value="create-tables" />
</properties>
</persistence-unit>
</persistence>
Bean Utilisateur.java
package com.jules.esiee.entities;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
import javax.persistence.*;
import com.jules.esiee.dao.UtilisateurDao;
#ManagedBean
#RequestScoped
#Entity
#Table(name="utilisateur")
public class Utilisateur {
#Id
#GeneratedValue( strategy = GenerationType.IDENTITY )
private long id;
#Column(name="nom")
private String nom;
#Column(name="prenom")
private String prenom;
#Column(name="age")
private int age;
#EJB
#Transient
private UtilisateurDao userDao;
public long getId()
{
return id;
}
public void setId(long _id)
{
id = _id;
}
public String getNom()
{
return nom;
}
public void setNom(String _nom)
{
nom = _nom;
}
public String getPrenom()
{
return prenom;
}
public void setPrenom(String _prenom)
{
prenom = _prenom;
}
public int getAge()
{
return age;
}
public void setAge(int _age)
{
age = _age;
}
public void sauvegarde() throws Exception
{
userDao.creer(this);
}
public void validationAge(FacesContext context, UIComponent component, Object convertedValue) throws ValidatorException {
this.age = (int) convertedValue;
if(!testAge())
{
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Vous êtes mineur",null));
}
}
public String validation()
{
FacesContext facesContext = FacesContext.getCurrentInstance();
if(!this.testAge())
{
facesContext.addMessage("f:age", new FacesMessage(FacesMessage.SEVERITY_ERROR,"Erreur sur l'âge, vous êtes mineur, bande de bouffons", "test"));
return null;
}
else
{
if(!alreadyInDB())
{
//this.sauvegarde();
return "listeUser";
}
else
{
facesContext.addMessage("f:nom", new FacesMessage(FacesMessage.SEVERITY_ERROR,"Utilisateur déjà existant", "test"));
return null;
}
}
}
public boolean alreadyInDB()
{
if(userDao.trouver(this) == null)
{
return false;
}
else
{
return true;
}
}
public boolean testAge()
{
if(this.age < 18) return false;
return true;
}
}
DAO UtilisateurDao.java
package com.jules.esiee.dao;
import java.io.Serializable;
import javax.persistence.*;
import javax.ejb.*;
import com.jules.esiee.entities.Utilisateur;
#Stateless
public class UtilisateurDao implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private static final String JPQL_SELECT_ALREADY = "SELECT u.prenom,u.nom,u.age FROM Utilisateur u WHERE u.prenom=:prenom AND u.nom=:nom AND u.age=:age";
// Injection du manager, qui s'occupe de la connexion avec la BDD
#PersistenceContext( unitName = "pro-jpa" )
private EntityManager em;
// Enregistrement d'un nouvel utilisateur
public void creer( Utilisateur utilisateur ) throws Exception {
try {
em.persist( utilisateur );
} catch ( Exception e ) {
throw new Exception( e );
}
}
// Recherche d'un utilisateur à parter de son adresse email
public Utilisateur trouver( Utilisateur _utilisateur){
Utilisateur utilisateur = null;
Query requete = em.createQuery( JPQL_SELECT_ALREADY );
requete.setParameter( "prenom", _utilisateur.getPrenom());
requete.setParameter("nom", _utilisateur.getNom());
requete.setParameter("age", _utilisateur.getAge());
try {
utilisateur = (Utilisateur) requete.getSingleResult();
} catch ( NoResultException e ) {
return null;
}
return utilisateur;
}
}
There are 2 problems:
When I persist a new user, it doesn't appear in the database. No exception is being thrown here.
When I select an existing user, it throws the following exception:
[Ljava.lang.Object; cannot be cast to com.jules.esiee.entities.Utilisateur
I don't really understand what the method getSingleResult() returns.
First I suggest to separate the Entity from the Managed Bean.The Entity should not know anything about the DAO or the Managed Bean. Secondly try annotate the method 'sauvegarde' in the DAO using #TransactionAttribute(TransactionAttributeType.REQUIRES_NEW).
Related
`HTTP Status 500 – Internal Server Error
Type Exception Report
Message Request processing failed: java.lang.NullPointerException: Cannot invoke "com.example.repository.StudentRepository.save(Object)" because "this.studentRepository" is null
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
jakarta.servlet.ServletException: Request processing failed: java.lang.NullPointerException: Cannot invoke "com.example.repository.StudentRepository.save(Object)" because "this.studentRepository" is null
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1018)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:913)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:731)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:884)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:814)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
Root Cause
java.lang.NullPointerException: Cannot invoke "com.example.repository.StudentRepository.save(Object)" because "this.studentRepository" is null
com.example.service.impl.StudentServiceImpl.saveStudent(StudentServiceImpl.java:37)
com.example.controller.StudentController.saveStudent(StudentController.java:45)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base/java.lang.reflect.Method.invoke(Method.java:568)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1080)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:973)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1010)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:913)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:731)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:884)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:814)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
Note The full stack trace of the root cause is available in the server logs.`
1.Controller Class
#Controller
public class StudentController {
private StudentService studentService;
public StudentController(StudentService studentService)
{
super();
this.studentService = studentService;
}
#GetMapping("/students")
public String listStudents()
{
//model.addAttribute("students",studentService.getAllStudent());
return "students";
}
#GetMapping("/students/new")
public String createStudentForm(Model model)
{
Student st = new Student();
model.addAttribute("student",st);
return "create_student";
}
#PostMapping("/students")
public String saveStudent(#ModelAttribute("student") Student student)
{
System.out.println("object: " + student.getFirstName()+"="+student.getEmail()+" = "+student.getLastName());
studentService.saveStudent(student);
return "redirect:/students";
}
}
2.Entity Class
package com.example.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
#Entity
#Table(name = "students")
public class Student {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "first_name", nullable = false)
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "email")
private String email;
public Student() {
}
public Student(String firstName, String lastName, String email) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
3.Student Repository Interface
package com.example.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.entity.Student;
public interface StudentRepository extends JpaRepository<Student, Long>{
}
4. Student Service
package com.example.service;
import java.util.List;
import com.example.entity.Student;
public interface StudentService {
List<Student> getAllStudents();
Student saveStudent(Student student);
Student getStudentById(Long id);
Student updateStudent(Student student);
void deleteStudentById(Long id);
}
4. Student Service Implementation
package com.example.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.entity.Student;
import com.example.repository.StudentRepository;
import com.example.service.StudentService;
#Service
public class StudentServiceImpl implements StudentService{
private StudentRepository studentRepository;
public StudentServiceImpl() {
super();
}
//#Autowired
public StudentServiceImpl(StudentRepository studentRepository) {
super();
System.out.println("Student Repo:= "+this.studentRepository);
this.studentRepository = studentRepository;
}
#Override
public List<Student> getAllStudents() {
return studentRepository.findAll();
}
#Override
public Student saveStudent(Student student) {
return studentRepository.save(student);
}
#Override
public Student getStudentById(Long id) {
return studentRepository.findById(id).get();
}
#Override
public Student updateStudent(Student student) {
return studentRepository.save(student); //.save(student);
}
#Override
public void deleteStudentById(Long id) {
studentRepository.deleteById(id);
}
}
Use #RequestBody instead of #ModelAttribute in controller save method.
#PostMapping("/students")
public String saveStudent(#RequestBody Student student)
{
System.out.println("object: " + student.getFirstName()+"="+student.getEmail()+" = "+student.getLastName());
studentService.saveStudent(student);
return "redirect:/students";
}
The error you are getting says that the studentRepository is null. This is because you have not autowired the studentRepository field or the constructor in the Student Service Implementation class. Try using the #Autowired on the
private StudentRepository studentRepository; field or on the Constructor method of the Student Service Implementation. Try this
4. Student Service Implementation
package com.example.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.entity.Student;
import com.example.repository.StudentRepository;
import com.example.service.StudentService;
#Service
public class StudentServiceImpl implements StudentService{
private StudentRepository studentRepository;
public StudentServiceImpl() {
super();
}
#Autowired
public StudentServiceImpl(StudentRepository studentRepository) {
super();
System.out.println("Student Repo:= "+this.studentRepository);
this.studentRepository = studentRepository;
}
#Override
public List<Student> getAllStudents() {
return studentRepository.findAll();
}
#Override
public Student saveStudent(Student student) {
return studentRepository.save(student);
}
#Override
public Student getStudentById(Long id) {
return studentRepository.findById(id).get();
}
#Override
public Student updateStudent(Student student) {
return studentRepository.save(student); //.save(student);
}
#Override
public void deleteStudentById(Long id) {
studentRepository.deleteById(id);
}
}
or
4. Student Service Implementation
package com.example.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.entity.Student;
import com.example.repository.StudentRepository;
import com.example.service.StudentService;
#Service
public class StudentServiceImpl implements StudentService{
#Autowired
private StudentRepository studentRepository;
public StudentServiceImpl() {
super();
}
public StudentServiceImpl(StudentRepository studentRepository) {
super();
System.out.println("Student Repo:= "+this.studentRepository);
this.studentRepository = studentRepository;
}
#Override
public List<Student> getAllStudents() {
return studentRepository.findAll();
}
#Override
public Student saveStudent(Student student) {
return studentRepository.save(student);
}
#Override
public Student getStudentById(Long id) {
return studentRepository.findById(id).get();
}
#Override
public Student updateStudent(Student student) {
return studentRepository.save(student); //.save(student);
}
#Override
public void deleteStudentById(Long id) {
studentRepository.deleteById(id);
}
}
Let me know if you face any more issues.
I’m using ‘graphql-spqr-spring-boot-starter’ library version 0.0.4 of ‘io.leangen.graphql’. I'm able to customize errors. See the below code and screenshot for reference:
Models:
#Getter
#Setter
#ToString
#Entity
#Accessors
public class Student {
#Id
#GraphQLQuery(name = "id", description = "A Student's ID")
private Long id;
#GraphQLQuery(name = "name", description = "A student's name")
private String name;
private String addr;
}
Service class:
#Service
#GraphQLApi
public class StudentService{
private final StudentRepository studentRepository;
private final AddressRepository addressRepository;
public StudentService(StudentRepository studentRepository, AddressRepository addressRepository) {
this.addressRepository = addressRepository;
this.studentRepository = studentRepository;
}
#GraphQLQuery(name = "allStudents")
public List<Student> getAllStudents() {
return studentRepository.findAll();
}
#GraphQLQuery(name = "student")
public Optional<Student> getStudentById(#GraphQLArgument(name = "id") Long id) {
if(studentRepository.findById(id) != null)
return studentRepository.findById(id);
throw new StudentNotFoundException("We were unable to find a student with the provided id", "id");
}
#GraphQLMutation(name = "saveStudent")
public Student saveStudent(#GraphQLArgument(name = "student") Student student) {
if(student.getId() == null)
throw new NoIdException("Please provide an Id to create a Student entry.");
return studentRepository.save(student);
}
}
Customized Exception class:
import java.util.List;
import graphql.ErrorType;
import graphql.GraphQLError;
import graphql.language.SourceLocation;
public class NoIdException extends RuntimeException implements GraphQLError {
private String noIdMsg;
public NoIdException(String noIdMsg) {
this.noIdMsg = noIdMsg;
}
#Override
public List<SourceLocation> getLocations() {
// TODO Auto-generated method stub
return null;
}
#Override
public ErrorType getErrorType() {
// TODO Auto-generated method stub
return ErrorType.ValidationError;
}
#Override
public String getMessage() {
// TODO Auto-generated method stub
return noIdMsg;
}
}
However, I’m not sure how to get rid of Exception while fetching data (/saveStudent) as seen on the above screenshot for the message field. I know we can have GraphQLExceptionHandler class which implements GraphQLErrorHandler (graphql-java-kickstart). But what is the option for sqpr-spring-boot-starter?
import graphql.*;
import graphql.kickstart.execution.error.*;
import org.springframework.stereotype.*;
import java.util.*;
import java.util.stream.*;
#Component
public class GraphQLExceptionHandler implements GraphQLErrorHandler {
#Override
public List<GraphQLError> processErrors(List<GraphQLError> list) {
return list.stream().map(this::getNested).collect(Collectors.toList());
}
private GraphQLError getNested(GraphQLError error) {
if (error instanceof ExceptionWhileDataFetching) {
ExceptionWhileDataFetching exceptionError = (ExceptionWhileDataFetching) error;
if (exceptionError.getException() instanceof GraphQLError) {
return (GraphQLError) exceptionError.getException();
}
}
return error;
}
}
Could someone please help me how can I remove this statement and send just the specific message?
You can create a Bean and override DataFetcherExceptionHandler. To override it, you have to override the execution strategy too:
#Bean
public GraphQL graphQL(GraphQLSchema schema) {
return GraphQL.newGraphQL(schema)
.queryExecutionStrategy(new AsyncExecutionStrategy(new CustomDataFetcherExceptionHandler()))
.mutationExecutionStrategy(new AsyncSerialExecutionStrategy(new CustomDataFetcherExceptionHandler()))
.build();
}
private static class CustomDataFetcherExceptionHandler implements DataFetcherExceptionHandler {
#Override
public DataFetcherExceptionHandlerResult onException(DataFetcherExceptionHandlerParameters handlerParameters) {
Throwable exception = handlerParameters.getException();
SourceLocation sourceLocation = handlerParameters.getSourceLocation();
CustomExceptionWhileDataFetching error = new CustomExceptionWhileDataFetching(exception, sourceLocation);
return DataFetcherExceptionHandlerResult.newResult().error(error).build();
}
}
private static class CustomExceptionWhileDataFetching implements GraphQLError {
private final String message;
private final List<SourceLocation> locations;
public CustomExceptionWhileDataFetching(Throwable exception, SourceLocation sourceLocation) {
this.locations = Collections.singletonList(sourceLocation);
this.message = exception.getMessage();
}
#Override
public String getMessage() {
return this.message;
}
#Override
public List<SourceLocation> getLocations() {
return this.locations;
}
#Override
public ErrorClassification getErrorType() {
return ErrorType.DataFetchingException;
}
}
I am new to Neo4j and I want to connect a node (Person) with a node (Asset) but also, store the time that this connection has been created. I figured out that I have to use #RelatedtoVia annotation. I have followed the Spring cineasts tutorial ([https://github.com/spring-projects/spring-data-neo4j/tree/master/spring-data-neo4j-examples/cineasts][1] ) Although, everything works fine as far as the tests and the database population are concerned, I get weird results at the REST service. Here is my code:
Node Person
import org.neo4j.helpers.collection.IteratorUtil;
import org.springframework.data.neo4j.annotation.*;
import org.springframework.data.neo4j.template.Neo4jOperations;
import java.util.*;
#NodeEntity
public class Person {
#GraphId
Long id;
#Indexed
private String displayName;
#Indexed(unique = true, failOnDuplicate = true)
private Long personId;
private String firstName;
private String lastName;
private Date birthday;
private String aboutMe;
private String thumbnailURL;
private String email;
private enum gendertypes {male, female, other};
private gendertypes gender;
private String[] languages;
private boolean active;
public static final String CONSUMED = "CONSUMED";
//empty & full constructor
//getters&setters
#RelatedToVia(type = "CONSUMED", elementClass = ConsumedDate.class)
#Fetch
Iterable<ConsumedDate> consumedDates;
public ConsumedDate consumedDate(Neo4jOperations template, Asset asset, Date timestamp) {
final ConsumedDate consumedDate = template.createRelationshipBetween(this, asset, ConsumedDate.class, CONSUMED, false).consumedDate(timestamp);
return template.save(consumedDate);
}
public Collection<ConsumedDate> getConsumedDates() {
return IteratorUtil.asCollection(consumedDates);
}
}
Node Asset
import org.neo4j.helpers.collection.IteratorUtil;
import org.springframework.data.neo4j.annotation.*;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import static org.neo4j.graphdb.Direction.INCOMING;
#NodeEntity
public class Asset {
#GraphId
private Long id;
#Indexed(unique=true, failOnDuplicate = true)
private Long assetId;
private String description;
private String type;
private String[] tags;
public Asset() {}
public Asset(Long assetId, String description, String type, String[] tags) {
this.assetId = assetId;
this.description = description;
this.type = type;
this.tags = tags;
}
public Long getAssetId() {return assetId; }
public void setAssetId(Long assetId) {
this.assetId = assetId;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String[] getTags() {
return tags;
}
public void setTags(String[] tags) {
this.tags = tags;
}
#RelatedTo(type = "CONSUMED", direction = INCOMING)
Set<Person> persons;
#RelatedToVia(type="CONSUMED", elementClass=ConsumedDate.class, direction=INCOMING)
#Fetch
Iterable<ConsumedDate> consumedDates;
public Collection<Person> getPersons() {
return persons;
}
public Collection<ConsumedDate> getConsumedDates() {
Iterable<ConsumedDate> allConsumedDates = consumedDates;
return allConsumedDates == null ? Collections.<ConsumedDate>emptyList() : IteratorUtil.asCollection(allConsumedDates);
}
#Override
public String toString() {
return "An asset with ID " + assetId + " description " + description + " type " + type;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Asset asset = (Asset) o;
if (id == null) return super.equals(o);
return id.equals(asset.id);
}
#Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}
Relationship Entity ConsumedDate
import org.springframework.data.neo4j.annotation.EndNode;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.RelationshipEntity;
import org.springframework.data.neo4j.annotation.StartNode;
import java.util.Date;
#RelationshipEntity(type = "CONSUMED")
public class ConsumedDate {
#GraphId
Long id;
#EndNode
Asset asset;
#StartNode
Person person;
Date timestamp;
public ConsumedDate consumedDate(Date timestamp){
this.timestamp=timestamp;
return this;
}
public Asset getAsset() {
return asset;
}
public Person getPerson() {
return person;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ConsumedDate consumedDate = (ConsumedDate) o;
if (id == null) return super.equals(o);
return id.equals(consumedDate.id);
}
#Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}
Controller
import gr.ntua.sam.context.neo4j.AssetRepository;
import gr.ntua.sam.context.neo4j.LocationRepository;
import gr.ntua.sam.context.neo4j.PersonRepository;
import gr.ntua.sam.context.resources.*;
import com.wordnik.swagger.annotations.ApiOperation;
import org.neo4j.graphdb.NotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.text.ParseException;
import java.util.*;
import java.util.List;
#RestController
#Configuration
#EnableNeo4jRepositories
public class ContextController {
#Autowired
Neo4jTemplate template;
#Autowired
AssetRepository assetRepository;
#Autowired
PersonRepository personRepository;
#ApiOperation(value = "Show the available assets", response = Asset.class)
#RequestMapping(value = "/asset", method = RequestMethod.GET)
public ResponseEntity<List<Asset>> getAssets() throws NotFoundException {
List<Asset> results = assetRepository.all();
return new ResponseEntity<List<Asset>>(results, HttpStatus.OK);
}
#ApiOperation(value = "Create a new asset",response = Asset.class)
#RequestMapping(value = "/asset", method = RequestMethod.POST, consumes = "application/json")
public ResponseEntity<Asset> saveAsset(#RequestBody Asset asset) {
Asset savedAsset = assetRepository.save(asset);
return new ResponseEntity<Asset>(savedAsset, HttpStatus.CREATED);
}
//Persons
#ApiOperation(value = "Get a list of all the available Persons")
#RequestMapping(value = "/person", method = RequestMethod.GET)
public ResponseEntity<List<Person>> getPersons() throws ParseException {
List<Person> results = personRepository.all();
return new ResponseEntity<List<Person>>(results, HttpStatus.OK);
}
#ApiOperation(value = "Creates a new Person node to store information about a user", response = Person.class)
#RequestMapping(value = "/person", method = RequestMethod.POST, consumes = "application/json")
public ResponseEntity<Person> savePerson(#RequestBody Person person) {
Person savedPerson = personRepository.save(person);
return new ResponseEntity<Person>(savedPerson, HttpStatus.CREATED);
}
#ApiOperation(value = "Creates relationship between a Person and an Asset")
#RequestMapping(value = "/person/{personId}/consumes/", method = RequestMethod.POST, consumes = "application/json")
public ResponseEntity<Void> consumes(#PathVariable("personId") Long personId, #RequestBody LinkedAsset linkedAsset) {
Person person = personRepository.findByPersonId(personId);
List<Long> assetIds = linkedAsset.getAssetIDs();
for (Long assetId : assetIds) {
Asset currentAsset = assetRepository.findByAssetId(assetId);
Date date= linkedAsset.getTimestamp();
ConsumedDate consumedDate= person.consumedDate(template,currentAsset,date);
template.save(consumedDate);
}
return new ResponseEntity<Void>(HttpStatus.CREATED);
}
The problem is that when I create a relationship between a Person and an Asset, along with a timestamp (I have created the class LinkedAsset which serves as a JSON input model and has nothing to do with Neo4j) and then try to get through REST the person or the asset, all I get is something definitely not JSON with the person or the asset appearing infinite times. Is there a way to face this problem?
Thank you in advance!
I am using TomeEE + MySql and i have problem because function createNamedQuery don't returns any results. I thought that problem is with my
entityManager but i checked in debugMode and is injected.
This is my code:
User Entity:
package pl.gsite.db.model;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
#Entity
#Table(name = "user")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "User.loginAndPassword", query = "SELECT u FROM User u WHERE u.login = :login and u.password = :password"),
#NamedQuery(name = "User.findAll", query = "SELECT u FROM User u"),
#NamedQuery(name = "User.findById", query = "SELECT u FROM User u WHERE u.id = :id"),
#NamedQuery(name = "User.findByLogin", query = "SELECT u FROM User u WHERE u.login = :login"),
#NamedQuery(name = "User.findByPassword", query = "SELECT u FROM User u WHERE u.password = :password")})
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Column(name = "id")
private Integer id;
#Size(max = 100)
#Column(name = "login")
private String login;
#Size(max = 100)
#Column(name = "password")
private String password;
public User() {
}
public User(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof User)) {
return false;
}
User other = (User) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "pl.gsite.db.model.User[ id=" + id + " ]";
}
}
My ManagedBean:
package pl.gsite.bean.request;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateful;
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.spi.Context;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import pl.gsite.bean.session.LoggedUserBean;
import pl.gsite.db.model.User;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContextType;
import javax.persistence.Query;
#Named(value = "loginRequest")
#RequestScoped
public class LoginRequest {
#PersistenceContext(unitName = "gsitePU")
private EntityManager em;
#Inject
private LoggedUserBean loggedUserBean;
private String login;
private String password;
public LoginRequest() {
}
public String authentication() {
try {
List<User> uList = new ArrayList<User>();
TypedQuery qq = em.createNamedQuery("User.findAll", User.class);
uList = qq.getResultList(); // <-- returns empty list
TypedQuery<User> query = em.createNamedQuery("User.loginAndPassword", User.class).setParameter("login", login).setParameter("password", password);
User u = query.getSingleResult(); // <-- throws an NoResultException
this.loggedUserBean.setLoggedUser(u);
}
catch(NoResultException e) {
e.printStackTrace();
}
return "index";
}
/**
* #return the login
*/
public String getLogin() {
return login;
}
/**
* #param login the login to set
*/
public void setLogin(String login) {
this.login = login;
}
/**
* #return the password
*/
public String getPassword() {
return password;
}
/**
* #param password the password to set
*/
public void setPassword(String password) {
this.password = password;
}
}
persistance.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="gsitePU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>gsite_mysql</jta-data-source>
<properties>
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(foreignKeys=true)"/>
</properties>
</persistence-unit>
</persistence>
I had the same issue. I changed the jpa persistence from openJPA to eclipseLink. The problem resolved.
I am deleveloping web project EJB,JPA - Hibernate as provider, JBoss 6,MySql.
I new in EJB, JPA.I have problems with load ejb bean in servlet.
persistence.xml
<persistence-unit name="LibraryPersistenceUnit" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/MySqlDS</jta-data-source>
<class>library.entity.User</class>
<class>library.entity.Book</class>
<properties>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
</properties>
</persistence-unit>
UserFacade.java
#Local
public interface UserFacade {
User findUserByLoginAndPassword(String login, String password);
/* List<User> getClients();
void returnBooks(long userId, long[] ids);
void takeBooks(long userId, long[] ids);*/
}
UserFacadeImpl.java
package library.facades.impl;
import library.dao.impl.UserDAO;
import library.entity.User;
import library.facades.interfaces.UserFacade;
import javax.ejb.EJB;
import javax.ejb.Stateless;
#Stateless
public class UserFacadeImpl implements UserFacade {
#EJB
private UserDAO userDAO;
public UserFacadeImpl() {
}
public User findUserByLoginAndPassword(String login, String password) {
User user = userDAO.selectUserByLoginAndPassword(login, password);
return user;
}
/* public List<User> getListClients() {
List<User> userList = userDAO.getClients();
return userList;
}
public void returnBooks(long userId, long[] ids) {
userDAO.returnBooks(userId, ids);
}
public void takeBooks(long userId, long[] ids) {
userDAO.takeBooks(userId, ids);
}*/
}
UserDAO.java
package library.dao.impl;
import library.dao.interfaces.GenericDAO;
import library.entity.User;
import javax.ejb.Local;
import javax.ejb.Stateless;
import java.util.HashMap;
import java.util.Map;
#Stateless
public class UserDAO extends GenericDAO {
public UserDAO() {
super(User.class);
}
public User selectUserByLoginAndPassword(String login, String password) {
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("login", login);
parameters.put("password", password);
return (User) super.findOneResult(User.SELECT_USER_BY_LOGIN_AND_PASSWORD, parameters);
}
/*public List<User> getClients() {
Query namedQuery = entityManager.createNamedQuery(User.ALL_CLIENTS, User.class);
List<User> clientsList = namedQuery.getResultList();
return clientsList;
}
#Override
public void returnBooks(long userId, long[] ids) {
User user = entityManager.find(User.class, userId);
for (long id : ids) {
Book book = entityManager.find(Book.class, id);
user.getTakenBooks().remove(book);
}
entityManager.merge(user);
}
#Override
public void takeBooks(long userId, long[] ids) {
User user = entityManager.find(User.class, userId);
for (long id : ids) {
Book book = entityManager.find(Book.class, id);
user.getTakenBooks().add(book);
}
entityManager.merge(user);
}*/
}
GenericDAO.java
package library.dao.interfaces;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.List;
import java.util.Map;
public abstract class GenericDAO<T> {
private static final String LIBRARY_PERSISTENCE_UNIT = "LibraryPersistenceUnit";
#PersistenceContext(unitName = LIBRARY_PERSISTENCE_UNIT)
private EntityManager entityManager;
private Class<T> entityClass;
public GenericDAO() {
}
public GenericDAO(Class<T> entityClass) {
this.entityClass = entityClass;
}
public void save(T entity) {
entityManager.persist(entity);
}
protected void delete(Object id, Class<T> classe) {
T entityToBeRemoved = entityManager.getReference(classe, id);
entityManager.remove(entityToBeRemoved);
}
public T update(T entity) {
return entityManager.merge(entity);
}
public T find(int entityID) {
return entityManager.find(entityClass, entityID);
}
// Using the unchecked because JPA does not have a
// entityManager.getCriteriaBuilder().createQuery()<T> method
#SuppressWarnings({"unchecked", "rawtypes"})
public List<T> findAll() {
/* CriteriaQuery cq = entityManager.getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));*/
return null;//entityManager.createQuery(cq).getResultList();
}
// Using the unchecked because JPA does not have a
// ery.getSingleResult()<T> method
#SuppressWarnings("unchecked")
protected T findOneResult(String namedQuery, Map<String, Object> parameters) {
T result = null;
try {
Query query = entityManager.createNamedQuery(namedQuery);
// Method that will populate parameters if they are passed not null and empty
if (parameters != null && !parameters.isEmpty()) {
populateQueryParameters(query, parameters);
}
result = (T) query.getSingleResult();
} catch (Exception e) {
System.out.println("Error while running query: " + e.getMessage());
e.printStackTrace();
}
return result;
}
private void populateQueryParameters(Query query, Map<String, Object> parameters) {
for (Map.Entry<String, Object> entry : parameters.entrySet()) {
query.setParameter(entry.getKey(), entry.getValue());
}
}
public EntityManager getEntityManager() {
return entityManager;
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
}
LibraryController
package library.controller;
import library.entity.User;
import library.facades.interfaces.UserFacade;
import library.resourses.constants.Constants;
import library.resourses.enums.Role;
import javax.ejb.EJB;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class LibraryController extends HttpServlet {
#EJB
private UserFacade userFacade;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {
performAction(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {
performAction(request, response);
}
private void performAction(HttpServletRequest request, HttpServletResponse response) {
String pageType = request.getParameter(Constants.PAGE_TYPE);
if (pageType != null) {
try {
String page = null;
String login = request.getParameter(Constants.USER_LOGIN);
String password = request.getParameter(Constants.USER_PASSWORD);
User user = userFacade.findUserByLoginAndPassword(login, password);
if (user == null) {
request.getSession().setAttribute(Constants.ERROR,
Constants.ERROR_MESSAGE_7);
page = Constants.MAIN_PAGE;
} else {
String namePage = user.getRole().toString().toLowerCase();
if (isClient(user)) {
request.getSession().setAttribute(Constants.CLIENT,
user);
request.getSession().setAttribute(Constants.ERROR, null);
} else if (isAdministrator(user)) {
request.getSession().setAttribute(Constants.ADMINISTRATOR,
user);
request.getSession().setAttribute(Constants.ERROR, null);
}
page = Constants.START_PAGES + namePage + Constants.END_PAGES;
}
RequestDispatcher requestDispatcher = getServletContext().getRequestDispatcher(page);
requestDispatcher.forward(request, response);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private boolean isAdministrator(User user) {
return user.getRole().equals(Role.ADMINISTRATOR);
}
private boolean isClient(User user) {
return user.getRole().equals(Role.CLIENT);
}
}
I get null for userFacade.Can you explain me what I do wrong.
Thanks.
The problem is that instead of letting the container instantiate and inject the DAO for you, you explicitely create the DAO instance by yourself:
private IUserDAO dao;
public UserService() {
dao = UserDAOImpl.getInstance();
}
For the EntityManager to be injected into the DAO, the container must instantiate it, not you. Replace the above code with the following, which uses dependency injection, and will thus also have the advantage of making your code testable:
#Inject
private IUserDAO dao;