I'm trying to get data from MySql Database by custom jpql #query method. I'm not receiving any error, but my list of results is empty.
In console hibernate show results like this:
Hibernate: select flight0_.id as id1_0_, flight0_.arrival_city as arrival_2_0_, flight0_.date_of_departure as date_of_3_0_, flight0_.departure_city as departur4_0_, flight0_.estimated_departure_time as estimate5_0_, flight0_.flight_number as flight_n6_0_, flight0_.operating_airlines as operatin7_0_ from flight flight0_ where flight0_.departure_city=? and flight0_.arrival_city=? and flight0_.date_of_departure=?
I tried to add annotations in model classes like #Column but nothing changed.
Typing lower or uppercase, still nothing. Any suggestions on how to solve this problem?
In this link you can see how my JSP pages, database table and view in the browser looks like https://imgur.com/a/uwBoDmI
#Entity
public class Flight extends AbstractEntity{
private String flightNumber;
private String operatingAirlines;
private String departureCity;
private String arrivalCity;
private Date dateOfDeparture;
private Timestamp estimatedDepartureTime;
Below are getters and setters for those fields.
public interface FlightRepository extends JpaRepository<Flight, Long> {
#Query("from Flight where departureCity=:departureCity and arrivalCity=:arrivalCity and dateOfDeparture=:dateOfDeparture")
List<Flight> findFlights(#Param("departureCity") String from, #Param("arrivalCity") String to,
#Param("dateOfDeparture") Date departureDate);
}
#Controller
public class FlightController {
#Autowired
FlightRepository flightRepository;
#RequestMapping("findFlights")
public String findFlights(#RequestParam("from") String from,#RequestParam("to") String to,
#RequestParam("departureDate") #DateTimeFormat(pattern = "MM-dd-yyyy") Date departureDate, ModelMap modelMap)
{
List<Flight> findFlights = flightRepository.findFlights(from, to, departureDate);
modelMap.addAttribute("flights",findFlights);
for (Flight flightTMP : findFlights) {
System.out.println(flightTMP);
}
return "displayFlights";
}
}
Related
I'm trying to save a document in MongoDB collection via MongoRepository.save method. Here's my code.
The document class:
#Document(collection = "appointments")
public class AppointmentDocument extends AbstractCommonDocument {
#Id
private ObjectId _id;
#DBRef(lazy = true)
private ServiceDocument service;
#DBRef(lazy = true)
private FeedbackDocument feedback;
private String status;
private String appointmentType;
private String description;
private EmbeddedPeriod period;
private EmbeddedPeriod requestedPeriod;
#Deprecated
private ProviderFeedback providerFeedback;
private List<Participant> participants;
private List<AppointmentResponse> appointmentResponses;
#Deprecated
private AppointmentPayment paymentDetails;
private CommunityPayment prePayment;
private CommunityPayment postPayment;
private boolean requestedByPatient;
#Deprecated
private DateTime acceptedAt;
private DateTime requestedAt;
private DateTime confirmedAt;
private DateTime cancelledAt;
private DateTime completedAt;
private String requestMessage;
private String mondayId;
...getters & setters
}
The repository:
#Repository
public interface AppointmentRepository extends MongoRepository<AppointmentDocument, String> {
}
Code for saving record.
AppointmentDocument appointmentDocument = new AppointmentDocument();
// ...omitted set calls for other fields for brevity
appointmentDocument.setRequestedByPatient(!isProvider);
appointmentDocument.setRequestedAt(requestedAt);
appointmentDocument.setRequestMessage(request.getComment());
appointmentDocument = appointmentRepository.save(appointmentDocument);
The problem is that all the fields are getting saved inside the database except requestedAt and requestMessage field. There are no error logs, I've enabled the MongoDB logs and it appears to be sending the insert query with all the fields present there.
DEBUG o.s.data.mongodb.core.MongoTemplate - 2021-04-21 19:22:58 - Inserting Document containing fields: [service, status, period, requestedPeriod, participants, appointmentResponses, prePayment, requestedByPatient, requestedAt, requestMessage, createdAt, lastModified, _class] in collection: appointments
Still I see that requestedAt and requestMessage is missing from the document in database.
I also tried updating the record after saving the document via mongoTemplate.updateFirst method. Still no luck. Here's the code for that.
mongoTemplate.updateFirst(
new Query(where("_id").is(appointmentDocument.get_id())),
new Update()
.set("requestedAt",requestedAt)
.set("requestMessage", request.getComment()),
AppointmentDocument.class
);
Again I see logs for updating..
DEBUG o.s.data.mongodb.core.MongoTemplate - 2021-04-21 19:22:58 - Calling update using query: { "_id" : { "$oid" : "60807b92adbe1d0001c2bed6" } } and update: { "$set" : { "requestedAt" : { "$date" : 1619032978091 }, "requestMessage" : "Dummy Request message" } } in collection: appointments
Still no luck. I got no clue why this is happening. Please help.
I have a simple API that expects three parameters and sends a response back, whenever I try to pass the three parameters I end up with an error
org.hibernate.hql.internal.ast.QuerySyntaxException: REPORTS
is not mapped [SELECT e FROM REPORTS e WHERE e.country =
:country AND e.projectId = :projectId AND e.code = :code]
The Model class
#Entity(name = "REPORTS")
#Table(name = "REPORTS")
public class DashboardModel {
public String Country;
public String Project;
public String HtmlContent;
public String FileName;
public String Code;
public String TeamLead;
public String Team;
public DateTime CreateDate;
public DateTime UpdateDate;
//boiler plate code
My Controller
#GetMapping(path = "/report/reportsheet")
public ResponseEntity<String> getReportSheet(#RequestParam("country") String country,
#RequestParam("projectId") String projectId,
#RequestParam("clusterNumber") String clusterNumber){
String report = dashboardService.getReport(country,projectId,clusterNumber);
//String report_ = wallboardService.getStateReportLabelByCountryProjectAndType(country,projectId,reportType);
return ResponseEntity.status(HttpStatus.OK).body(report);
My Service
public String getReport(String country,String projectId,String code){
TypedQuery<DashboardModel> query = entityManager.createQuery(
"SELECT e FROM REPORTS e WHERE e.country = :country AND e.projectId = :projectId AND e.code = :clusterNumber" , DashboardModel.class);
List<DashboardModel> dashboard = query
.setParameter("country", country)
.setParameter("projectId", projectId)
.setParameter("clusterNumber", code)
.getResultList();
return String.valueOf(dashboard);
}
How should I map the table correctly?
You have to use entity class names like DashboardModel in the JPQL and a table name REPORTS in the SQL.
The second parameter DashboardModel.class in the createQuery() is not related to entity class name in the SELECT clause.
You can just use createQuery(jpql) with one parameter, but that method returns a List without element type. So what the second parameter DashboardModel.class for.
You don't need to specify table name here #Entity(name = "REPORTS")
just #Entity
I guess the entity is not in a package that is scanned by Spring Boot. Here is an article about this: https://springbootdev.com/2017/11/13/what-are-the-uses-of-entityscan-and-enablejparepositories-annotations/
I would like to add, edit and get users via an API I have created. I can add users and get all users added via API requests on Postman but I can't get data for a specific user when I request it on Postman as all I get is a null response with a 200 OK status. How can I be able to get a specific user's information using its national Id?
This is how my entity looks like;
public class users {
#Id
private String Id;
#Field("nationalId")
#JsonProperty("nationalId")
private String nationalId;
#Field("userName")
#JsonProperty("userName")
private String userName;
#Field("userEmail")
#JsonProperty("userEmail")
private String userEmail;
#Field("userPin")
#JsonProperty("userPin")
private String userPin;
#Field("userContact")
#JsonProperty("userContact")
private String userContact;
#Field("imageUrl")
#JsonProperty("imageUrl")
private String imageUrl;
#Field("loanLimit")
#JsonProperty("loanLimit")
private String loanLimit;
}
My controller class looks like this;
class Controller {
#Autowired
private user_service User_Service;
#PostMapping("/save_user")
private users save (#RequestBody users Users){return User_Service.save(Users);}
#PutMapping("/update_user")
private users update (#RequestBody users Users){return User_Service.update(Users);}
#GetMapping("/all")
private List<users> getAllusers(){return User_Service.getAllusers();}
#GetMapping("/user/{nationalId}")
private Optional <users> getusers(#PathVariable String nationalId) {return User_Service.getusers(nationalId);}
#DeleteMapping("/delete_user/{nationalId}")
private void deleteUser (#PathVariable String nationalId){User_Service.deleteUser(nationalId);}
}
My user service look like this;
public interface user_service {
users save (users Users);
users update (users Users);
List<users> getAllusers();
Optional<users> getusers(String nationalId);
void deleteUser (String nationalId);
}
You need to specify the name attribute in PathVariable annotation as #PathVariable(name="nationalId")
you need to have a method call like this to get a specific by national id.
Optional<user> getUserByNationalId(String nationalId);
for spring to understand what it is you want to fetch it cant figure it out by just passing in a string.
(And please rename your class User, and not users. The class represents a single user, and also please use camel casing)
I was trying to use Spring Data JPA on Spring Boot and I kept getting error, I can't figure out what the problem is:
Unable to locate Attribute with the the given name [firstName] on
this ManagedType [com.example.h2demo.domain.Subscriber]
FirstName is declared in my entity class. I have used a service class with DAO before with different project and worked perfectly.
My Entity class (getters and setters are also in the class) :
#Entity
public class Subscriber {
#Id #GeneratedValue
private long id;
private String FirstName,LastName,Email;
public Subscriber(long id, String firstName, String lastName, String email) {
this.id = id;
this.FirstName = firstName;
this.LastName = lastName;
this.Email = email;
}
}
...
My Repository Class
#Component
public interface SubscriberRepository extends JpaRepository<Subscriber,Long> {
Subscriber findByFirstName(String FirstName);
Subscriber deleteAllByFirstName(String FirstName);
}
My Service Class
#Service
public class SubscriberService {
#Autowired
private SubscriberRepository subscriberRepository;
public Subscriber findByFirstName(String name){
return subscriberRepository.findByFirstName(name);
}
public Subscriber deleteAllByFirstName(String name){
return subscriberRepository.deleteAllByFirstName(name);
}
public void addSubscriber(Subscriber student) {
subscriberRepository.save(student);
}
}
And My Controller class:
#RestController
#RequestMapping("/subscribers")
public class SubscriberController {
#Autowired
private SubscriberService subscriberService;
#GetMapping(value = "/{name}")
public Subscriber findByFirstName(#PathVariable("name") String fname){
return subscriberService.findByFirstName(fname);
}
#PostMapping( value = "/add")
public String insertStudent(#RequestBody final Subscriber subscriber){
subscriberService.addSubscriber(subscriber);
return "Done";
}
}
Try changing private String FirstName,LastName,Email; to private String firstName,lastName,email;
It should work.
findByFirstName in SubscriberRepository tries to find a field firstName by convention which is not there.
Further reference on how properties inside the entities are traversed https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-property-expressions
The same problem was when i had deal with Spring Data Specifications (https://www.baeldung.com/rest-api-search-language-spring-data-specifications)
Initial piece of code was:
private Specification<Project> checkCriteriaByProjectNumberLike(projectNumber: String) {
(root, query, criteriaBuilder) -> criteriaBuilder.like(root.get("project_number"), "%" + projectNumber)
}
The problem was in root.get("project_number"). Inside the method, I had to put the field name as in the model (projectNumber), but I sent the field name as in the database (project_number).
That is, the final correct decision was:
private Specification<Project> checkCriteriaByProjectNumberLike(projectNumber: String) {
(root, query, criteriaBuilder) -> criteriaBuilder.like(root.get("projectNumber"), "%" + projectNumber)
}
After I change my entity class variables from capital letter to small letter for instance Username to username the method Users findByUsername(String username); is working for me now .
As per specification , the property names should start with small case.
...The resolution algorithm starts with interpreting the entire part (AddressZipCode) as the property and checks the domain class for a property with that name (uncapitalized)....
It will try to find a property with uncapitalized name. So use firstName instead of FristName and etc..
Assume a model named User:
#Entity
public class User extends Model {
#Id
#Constraints.Min(10)
public Long id;
#Constraints.Required
public String username;
#Constraints.Required
public String password;
public static Finder<Long, User> find = new Finder<Long, User>(
Long.class, User.class
);
}
When I attempt to update an instance of User in my controller:
User user = User.find.where().eq("username", username).findUnique();
if(user != null) {
user.username = "some_new_username";
user.save();
}
no changes seem to be committed. I read somewhere that when you alter a model instance by its property, it does not get dirty and therefore no changes take place. Hence you should use a setter instead. In the documentation of Play Framework it is said that those setters (and getters) are generated automatically, but using user.setUsername(username) gives me a compilation error:
cannot find symbol [symbol: method setUsername(java.lang.String)] [location: class models.User]
Am I missing something?
Have you tried adding custom setters?
#Entity
public class User extends Model {
#Id
#Constraints.Min(10)
public Long id;
#Constraints.Required
public String username;
public void setUsername(String _username) {
username = _username;
}
#Constraints.Required
public String password;
public void setPassword(String _password) {
password = _password;
}
public static Finder<Long, User> find = new Finder<Long, User>(
Long.class, User.class
);
}
As far as I can tell, automatic getter/setter translation is broken in Play2. Your assignment:
user.username = "some_new_username";
should have triggered the function call:
user.setUsername("some_new_username");
This translation seems to be broken in Play 2. Here's my own question on the subject.