This is my entity class.
#NamedQueries({ #NamedQuery(name = UsersEntity.NAMED_QUERY_SELECT_ALL_BY_MANAGER_ROLE,
query = "SELECT e FROM " + UsersEntity.ENTITY_NAME + " e WHERE e." +
UsersEntity.FIELD_NAME_USER_ROLE + " = '" +
UsersVO.USER_ROLE + "'") })
#Column(name = "USER_ROLE", nullable = false, length = 30)
private String userRole;
public static final String FIELD_NAME_USER_ROLE = "userRole";
This is the java class from where i execute query
#GET
#Path("/userrole")
#Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public UsersListVO getUsers(#QueryParam("userRole") String userRole) {
// public UsersListVO getUsers(){
System.out.println(">>>>>here");
UsersListVO usersListVO = new UsersListVO();
try {
List<UsersEntity> usersEntityList = em.createNamedQuery(UsersEntity.NAMED_QUERY_SELECT_ALL_BY_MANAGER_ROLE, UsersEntity.class).setParameter(UsersEntity.FIELD_NAME_USER_ROLE, userRole).getResultList();
The test case is :-
#Test
public void testGetUsers() {
System.out.println("Start test ");
UsersListVO usersListVO = baseWebTarget.path("userrole").queryParam("userRole", "AppSystemManagerUserRole").request(MediaType.APPLICATION_JSON).get(UsersListVO.class);
if (usersListVO.getStatusType().equals(StatusTypeVO.FAILURE)) {
Assert.fail(usersListVO.getMessage());
} else {
System.out.println(usersListVO.getMessage());
}
}
I want to fetch all the managers whose roles are managerRole from users table.But got error while executing the test case in to my jdeveloper. The error i got is
java.lang.AssertionError: You have attempted to set a parameter value
using a name of userRole that does not exist in the query string
SELECT e FROM UsersEntity e WHERE e.userRole =
'AppSystemManagerUserRole'.
The error
java.lang.AssertionError: You have attempted to set a parameter value using a name of userRole that does not exist in the query string SELECT e FROM UsersEntity e WHERE e.userRole = 'AppSystemManagerUserRole' is indicating the you are trying to set a parameter that doesn't exist in your named query.
Your named query:
query = "SELECT e FROM " + UsersEntity.ENTITY_NAME + " e WHERE e." +
UsersEntity.FIELD_NAME_USER_ROLE + " = '" + UsersVO.USER_ROLE + "'"
after string concatenation results in:
query = "SELECT e FROM UsersEntity e WHERE e.userRole = 'AppSystemManagerUserRole'"
As you can see there is not named parameter that you can set. And when you tried calling setParameter(UsersEntity.FIELD_NAME_USER_ROLE, userRole) it threw the exception.
You need to introduce named parameter as below in your named query that you allows you to set later in your code.
query = "SELECT e FROM " + UsersEntity.ENTITY_NAME + " e WHERE e." +
UsersEntity.FIELD_NAME_USER_ROLE + " = :" + UsersEntity.FIELD_NAME_USER_ROLE
would result in the
query = "SELECT e FROM UsersEntity e WHERE e.userRole = :userRole"
With this you should be able to set the parameter and should work.
Related
I have an update query on hibernate on this table
class PackEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String status;
private String oldStatus;
#ManyToOne
#JoinColumn(name = "order_id")
private OrderEntity order;
...
}
And on OrderEntity I have there another relationship to another table when I have machine names.
On the JPA repository, I have the query. Basically first I search by machine and status and then I want to update the old status to put the current value of the status field and in status to put the new status. This is it:
#Transactional
#Modifying(clearAutomatically = true)
#Query("UPDATE PackEntity p " +
"SET p.oldStatus= p.status, p.status = ?3 " +
"WHERE p.id IN " +
" ( SELECT p2" +
" FROM PackEntity p2" +
" JOIN p2.order " +
" JOIN p2.order.machine" +
" WHERE p2.order.machine.name = ?1 AND p2.status = ?2)")
List<PackEntity > updateAllWithStatusByMachineNameAndStatus(String machineName, String status, String newStatus);
Now I'm having this error .QueryExecutionRequestException: Not supported for DML operations [UPDATE com.pxprox.entities.PackEntity with root cause ...
Why not create a method that does this for you? Initializing the entity and updating everything, changes will be flushed automatically at the end of the transaction. You can have a look at updating entity with spring-data-jpa
It should basically be something like:
#Autowired
private PackEntityRepository packEntityRepository;
public void updatePackEntity(PackEntity newPE) {
PackEntity packEntity = packEntityRepository.findById(newPE.getId());
packEntity.setOldStatus = packEntity.getStatus();
packEntity.setStatus = newPE.getStatus();
packEntityRepository.save(packEntity);
}
The return type of the method is wrong and also the query should be a little adapted. Use the following:
#Transactional
#Modifying(clearAutomatically = true)
#Query("UPDATE PackEntity p " +
"SET p.oldStatus = p.status, p.status = ?3 " +
"WHERE EXISTS " +
" ( SELECT 1" +
" FROM PackEntity p2" +
" JOIN p2.order o " +
" JOIN o.machine m" +
" WHERE m.name = ?1 AND p2.status = ?2 AND p2.id = p.id)")
void updateAllWithStatusByMachineNameAndStatus(String machineName, String status, String newStatus);
or even better
#Transactional
#Modifying(clearAutomatically = true)
#Query("UPDATE PackEntity p " +
"SET p.oldStatus = p.status, p.status = ?3 " +
"WHERE p.status = ?2 AND EXISTS " +
" ( SELECT 1" +
" FROM p.order o " +
" JOIN o.machine m" +
" WHERE m.name = ?1)")
void updateAllWithStatusByMachineNameAndStatus(String machineName, String status, String newStatus);
My class begins with:
#Entity
#Table(name = "validate_info", catalog = "company")
#JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="#id")
public class ValidateInfo implements java.io.Serializable{
And my HQL Query:
List<ValidateInfo> lResult = null;
String lHql = " from ValidateInfo vi "
+ " where vi.document.idDocument in (:documentsList) "
+ " and vi.idEntityType = :idEntityType";
Query lQuery = pSession.createQuery(lHql);
lQuery.setParameterList("documentsList", pDocumentsList);
lQuery.setParameter("idEntityType", pIdEntityType);
lResult = lQuery.list();
The error I get:
[T0028][SEVER] .web.Control.execute() RunService returns Exception ValidateInfo is not mapped [ from ValidateInfo vi where vi.document.idDocument in (:documentsList) and vi.idEntityType = :idEntityType]
[T0028][SEVER] .web.Control.manageError() java.util.HashMap cannot be cast to java.util.List
Can you guys help me? I don't know why i get the "not Mapped" error, the name of the HQL query table is the same as the classname.
When you write an HQL query you must write the complete path of your used class.
So you can replace your code as follow:
String lHql = " from " + ValidateInfo.class.getName() + " vi "
+ " where vi.document.idDocument in (:documentsList) "
+ " and vi.idEntityType = :idEntityType";
I'm trying to run a JPA query to return only specific fields from my entity, rather than the entire entity (for performance reasons).
Within this entity is this:
#OneToMany(cascade = { CascadeType.ALL }, mappedBy = "helper", fetch = FetchType.EAGER)
#MapKeyColumn(name = "year")
public Map<Integer, DutyHistory> getDutyHistoryList() {
return dutyHistoryList;
}
I'd like, within my query, to return multiple values from this map e.g. fields from the DutyHistory object for the last 3 years.
My question is, what's the query syntax for this? I'm mapping the returned values to a POJO as below:
#Query(value = "SELECT new com.castlemon.helpers.dto.ReportHelper(h.helperId, h.firstName, h.secondName"
+ ", h.sex, h.service, h.dateOfBirth, h.schoolGroup, h.orientationRequired, h.notes as adminNotes "
+ ", h.primaryDuty.dutyName as primaryDuty, h.secondDuty, h.secondaryDuty.dutyName as secondaryDuty "
+ " WHERE h.travelling = 1")
public List<ReportHelper> getTravellingHelperDetails();
You should create another query with your "year" parameter
#Query(value = "SELECT new com.castlemon.helpers.dto.ReportHelper(h.helperId, h.firstName, h.secondName"
+ ", h.sex, h.service, h.dateOfBirth, h.schoolGroup, h.orientationRequired, h.notes as adminNotes "
+ ", h.primaryDuty.dutyName as primaryDuty, h.secondDuty, h.secondaryDuty.dutyName as secondaryDuty "
+ " WHERE h.travelling = 1 AND h.year >= :yearLimit")
public List<ReportHelper> getTravellingHelperDetailsUntilYear(String yearLimit);
I have a rather simple query that takes input for a few tables. When I try and run the query it says:
[ERROR] org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].
[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in
context with path [] threw exception [Request processing failed; nested
exception is org.springframework.dao.InvalidDataAccessApiUsageException:
org.hibernate.QueryException: could not instantiate class
[com.htd.domain.ShopOrder] from tuple; nested exception is
java.lang.IllegalArgumentException: org.hibernate.QueryException: could not
instantiate class [com.htd.domain.ShopOrder] from tuple] with root cause
java.lang.IllegalArgumentException: null
JPQL query:
#Query("SELECT NEW com.htd.domain.ShopOrder(po.id, po.po_number, "
+ "po.due_date, po_part.id, po_part.part_quantity, "
+ "part.id, part.part_number, part.part_description, "
+ "part.plasma_hrs_per_part, part.grind_hrs_per_part, "
+ "part.mill_hrs_per_part, part.brakepress_hrs_per_part) "
+ "FROM Po po "
+ "LEFT JOIN po.partList po_part "
+ "LEFT JOIN po_part.part part "
+ "LEFT JOIN po_part.part where po.id = ?1")
List<ShopOrder> getShopOrder(Long id);
ShopOrder.java
public ShopOrder(long po_id, String po_number, LocalDate po_due_date,
long po_part_id, int part_quantity, long part_id,
String part_number, String part_decription, BigDecimal plasma_hrs,
BigDecimal grind_hours, BigDecimal mill_hrs,
BigDecimal breakpress_hrs) {
this.po_id = po_id;
this.po_number = po_number;
this.po_due_date = po_due_date;
this.po_part_id = po_part_id;
this.part_quantity = part_quantity;
this.part_id = part_id;
this.part_number = part_number;
this.part_decription = part_decription;
this.plasma_hrs = plasma_hrs;
this.grind_hours = grind_hours;
this.mill_hrs = mill_hrs;
this.breakpress_hrs = breakpress_hrs;
}
I created a Juint test to see what was going on by doing the following:
#Test
#Transactional
public void shopOrderTest() throws Exception
{
Po po = new Po();
Long id = (long) 11;
LocalDate date = new LocalDate(2015,6,10);
po.setDue_date(date);
po.setId(id);
po.setPo_number("11254");
po.setSales_order_number("34879");
po.setStatus("ordered");
BigDecimal total_sale = new BigDecimal("55");
po.setTotal_sale(total_sale);
Part part = new Part();
BigDecimal brakepress_hrs_per_part = new BigDecimal("34");
part.setBrakepress_hrs_per_part(brakepress_hrs_per_part);
BigDecimal grind_hrs_per_part = new BigDecimal("354");
part.setGrind_hrs_per_part(grind_hrs_per_part);
part.setId(id);
part.setInventory_count(55);
BigDecimal laser_hrs_per_part = new BigDecimal("987");
part.setLaser_hrs_per_part(laser_hrs_per_part);
BigDecimal lb_per_part = new BigDecimal("58748");
part.setLb_per_part(lb_per_part);
poRes.save(po);
partRes.save(part);
List<ShopOrder> getOrders = po_partRepository.getShopOrder(id);
int size = getOrders.size();
System.out.println("The size is-----"+size);
for(ShopOrder order: getOrders){
System.out.println(order);
}
}
}
Now the test passes but the size of the List is 0 which explains why I am getting a null error. However I do not understand why.
The method that is giving me the null error is here:
/**
* Generate Shop Orders.
*/
#SuppressWarnings("null")
#RequestMapping(value = "/generateShopOrder/{id}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public void generate(#PathVariable Long id) throws URISyntaxException {
System.out.println("po id to generate = " + id);
List<ShopOrder> shopOrders = po_partRepository.getShopOrder(id);
for(ShopOrder<?> order: shopOrders) {
System.out.println("-------Printing Shop Orders" + order);
}
}
Po.java
#OneToMany(mappedBy="po",targetEntity=Po_part.class)
private List<Po_part> partList;
public List<Po_part> getPartList() {
return partList;
}
Part.java
#OneToMany(mappedBy="part",targetEntity=Po_part.class)
private List<Po_part> partList;
Po_part.java
#ManyToOne
private Part part;
#ManyToOne
private Po po;
I hope this clears things up with my query. If you have any suggestions on how I should do a better query I am all ears.
Here is a picture of my database tables too:
#Query("SELECT NEW com.htd.domain.ShopOrder(pp.po.id, pp.po.po_number, pp.po.due_date, pp.id, pp.part_quantity, "
+ "pp.part.id, pp.part.part_number, pp.part.part_description, pp.part.plasma_hrs_per_part, pp.part.grind_hrs_per_part, "
+ "pp.part.mill_hrs_per_part, pp/part.brakepress_hrs_per_part) "
+ "FROM Po_part pp Where pp.part.id = ?1")
List<ShopOrder> getShopOrder(Long id);
without join
#Query("SELECT NEW com.htd.domain.ShopOrder(po.id, po.po_number, po.due_date, po_part.id, po_part.part_quantity, "
+ "part.id, part.part_number, part.part_description, part.plasma_hrs_per_part, part.grind_hrs_per_part, "
+ "part.mill_hrs_per_part, part.brakepress_hrs_per_part) "
+ "FROM Po po "
+ "LEFT JOIN Po_part po_part ON po_part.po.id = po.id"
+ "LEFT JOIN Part part ON po_part.part.id = part.id AND po.part.id = ?1")
List<ShopOrder> getShopOrder(Long id);
with Left join
I have coded a method which selects or updates a value if it has a certain identifier:
#Transactional
public List<Settings> getSettingsByParameter(String identifier) throws Exception {
log.info("get resultsList by " + identifier);
if(identifier.isEmpty()) {
throw new Exception("Identifier is empty!");
}
if(identifier == "today") {
//update today field
String query = "UPDATE settings SET value=TODAY() where identifier = '" + identifier + "'";
em.merge(em.createQuery(query, Settings.class).getSingleResult());
}
String query = "SELECT p FROM Settings p WHERE identifier = '" + identifier + "'";
List<Settings> resultList = em.createQuery(query, Settings.class).getResultList();
return resultList;
}
However, I am getting an exception:
java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: settings is not mapped [UPDATE settings SET value=TODAY() where identifier = 'today']
Why and how is this possible using hibernate and hsqldb?
I really appreciate your answer!
Hibernate is case-sensitive with class names. Try it with a captial S for the Settings class:
String query = "UPDATE Settings SET value=TODAY() where identifier = '" + identifier + "'";