I have a query like:
#Query("select I from Indicator I where I.bankId in (:bankIds) ")
public List<Indicator> getIndicatorDetailsByBankIdList(#Param("bankIds") Set<Long> bankIdList);
This is working fine most of the time. At times it's throwing the following exception.
Description - Parameter with that name [bankIds] did not exist; nested exception is java.lang.IllegalArgumentException: Parameter with that name [bankIds] did not exist, StackTrace - java.lang.IllegalArgumentException: Parameter with that name [bankIds] did not exist
at org.hibernate.jpa.spi.BaseQueryImpl.findParameterRegistration(BaseQueryImpl.java:505)
at org.hibernate.jpa.spi.BaseQueryImpl.setParameter(BaseQueryImpl.java:631)
at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:180)
at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:49)
Observations
I'm not sure how right i'm adding in this observation, but i guess the service fails only when used inside modules which are little on the data heavy side (even here it fails only at times). Does memory issues cause these kind of exceptions to be thrown?
Inconsistant issue was observed on another method on the same entity:
#Query("select I from Indicator I where I.activityId in (:activityIds) ")
public List<Indicator> getIndicatorDetailsByActivityIdList(#Param("activityIds") Set<Long> acyIdList);
Related
Quick question regarding Java Micrometer with #Counted and #ExceptionHandler please.
I have a very straightforward #ExceptionHandler:
#ExceptionHandler
#Counted(value = "MY_EXCEPTION", description = "SOME_DESCRIPTION")
public Mono<ResponseEntity<String>> myCoolExceptionHandler(final RuntimeException runtimeException) {
System.err.println("an exception!" + runtimeException);
return Mono.just("bad");
}
I think this combination is quite interesting, as it gives visibility on exception happening. We can build dashboard, alerts, etc, quite cool.
Unfortunately, when I looked at the metric generated, it was something like:
# HELP MY_EXCEPTION_total SOME_DESCRIPTION
# TYPE MY_EXCEPTION_total counter
MY_EXCEPTION_total{class="package.MyController",exception="none",method="myCoolExceptionHandler",result="success",} 3.0
I am quite puzzled on exception="none" and result="success"
May I ask how those values got into the metric in the first place?
Also, how to change them into something more meaningful, such as the exception class for instance?
Thank you!
The annotated method itself does not throw an exception and always completes normally. Therefore, the intercepting code installed by the annotation will never record an exception (exception=none) and the outcome will always be good (result=success). Only exceptions thrown from within the annotated method will be recorded as an error outcome.
You can always manually record metrics by injecting the MetricRegistry and then registering a metric with the appropriate name and tags.
Is it possible (if so, how) would one add custom methods in the CrudRepository interface?
I have the following DAO with a entity class called, Foobar. For the sake of this question - the entity class can have any number of fields/columns.
package com.bar
import org.springframework.data.repository.CrudRepository;
import com.bar.Foobar
public interface FoobarCrudRepo extends CrudRepository<Foobar, Long> {
public Foobar findByObject(Foobar JObj);
}
This code works fine if you remove that custom method but throws an error if I add it (like above). My understanding from this post (Update or SaveorUpdate in CRUDRespository, Is there any options available) was that I just needed to add an additional method to the interface (as shown in the example) and the JPARepo will take care of the rest. However, I'm getting the error below. My thinking - it doesn't know much about this custom class.
Here's my error:
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'Foobar': Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property object found for type Foobar!
Why would I want a findbyObject() you might ask? So that I don't insert duplicate rows of data into the DB by checking the DB to see if the object has already been added and performing a check.
Any suggestions would help, thanks.
FindByObject doesn't look for an object, it literally looks for a field in your Foobar class named Object. Like others have mentioned, you can check other fields of the object to see if it already exists.
For example, if your Foobar class has String name and String email fields, you could create a method like public Foobar findByNameAndEmail(String name, String email) {}, and this would return a Foobar object if there was a record in the database that met these criteria.
All query methods do is replicate SQL, so ask yourself, could you "find by object (record)" in SQL? No, because that makes no sense. Your query would return a record (object) WHERE certain conditions are met.
Your code does not work because it takes the Names behind findBy and tries to create the where condition with that.
So findByObject creates:
where object = ?
to find the object by id you can call
findOne(?)
There is a String object called detailMessage in java.lang.Throwable class, which says the reason of any exception thrown in java code.
This object is initialized through a constructor using super(string message) statement or setter or whatever from subclasses like Exception and again from its subclasses like SQLException.
When SQLException is thrown, error message can be displayed using sqlExceptionObject.getMessage();
The error message in sqlExceptionObject.getMessage() is same as in MySQL tool (Incase of any error in query execution)
So is the error message copied from MySQL? If yes, then from where?
The JDBC driver is responsible for that. It could translate an error code it gets from the DB to a string or it could get the error string directly from the DB. I don't know which one is the case for MySQL.
I have entity Foo, which maps to sql table with some unique constraints. Thus saving Foo may fail. I am using FooDao to save Foo:
#Repository
public class FooDao
{
#Autowired
private SessionFactory sessionFactory;
#Transactional
#Override
public void add(Foo item) {
sessionFactory.save(item);
}
}
when I call method FooDao#add(Foo) it may fail for two reasons: either because of unique constraint violation (in this case, I know how to handle the problem) or because of some other problem (in this I probably should propagate the exception). How do I distinguish between those two situations?
I could add method find(Foo item) to FooDao and check, whether something like item, which I was trying to add is database. But this would require additional select from database and I am a bit worried about this.
Thats actually SQLState.
do something like this
Catch(HibernateException he){
SQLException sqe = he.getSQLEception();
String sqlState = sqe.getSQLState();
if(sqlState.equals("23000"){
// Handle your exception
}
}
Java doc:
SQLState - an XOPEN or SQL:2003 code identifying the exception
One link I found for ISO sqlStates,
link to reference
But look for exact reference and value..
One obvious (but maybe nasty) solution is that you catch javax.persistence.PersistenceException and parse the error message for "violant" or "constraint".
From my point of view you should do the select/find upfront. Remember that you are using an ORM! Hibernate has caches involved so neither the select/find nor the key contraint error might be the result of an actual db query but the result of an calculation of Hibernate based on your already in cache loaded data.
Sebastian
Catch org.hibernate.JDBCException. This has getErrorCode(). For unique constraint voilation its ORA-00001.
-Maddy
If there is a database exception it gets caught in a HibernateException, which is a checked exception. Spring wraps this in a DataAccessException, which is unchecked. This exception will run up to your Controller and out to the Servlet and end up in a stack trace in the browser and log file. You can catch this exception and print it out so you can see what is happening. This will at least get you to the point where you know what is actually breaking.
Bad keys is probably one issue. But bad values is probably another. Some non-null fields are null, or something isn't long/short enough etc. Fixing this probably involves validation. You can use the Hibernate Validator. You give your fields some nifty annotations and then you get validation errors in java before you even get to the database - errors happen faster.
I’ve been following the e-commerce tutorial located here: http://netbeans.org/kb/docs/javaee/ecommerce/intro.html
Code repo of project here.
I have ran into a few problems that I believe are related:
1: Trying to view the customers’ orders on the Admin page results in:
**WARNING**: EJB5184:A system exception occurred during an invocation on EJB OrderManager, method: public java.util.Map session.OrderManager.getOrderDetails(int)
**WARNING**: javax.ejb.EJBTransactionRolledbackException
**WARNING**: EJB5184:A system exception occurred during an invocation on EJB OrderedproductFacade, method: public java.util.List session.OrderedproductFacade.findByOrderId(java.lang.Object)
**WARNING**: javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean
Caused by: java.lang.IllegalArgumentException: You have attempted to set a parameter value using a name of customerOrderId that does not exist in the query string SELECT o FROM Orderedproduct o WHERE o.orderedproductPK.custOrderid = :custOrderid.
2: Trying to view details for a particular order in the admin page results in:
WARNING: StandardWrapperValve[AdminServlet]: PWC1406: Servlet.service() for servlet AdminServlet threw exception
Caused by: java.lang.IllegalArgumentException: You have attempted to set a parameter value using a name of customerOrderId that does not exist in the query string SELECT o FROM Orderedproduct o WHERE o.orderedproductPK.custOrderid = :custOrderid.
Both problems have the ‘findByOrderId’ method in common and I am at a loss as to what is wrong with it.
The offending method is located in the following directory: src/jsf_crud/src/java/session/OrderedProductFacade.java
(I would link it as a hyperlink but spam prevention measures prevent me)
Not sure what the best course of action is, any recommendations?
Your query needs a parameter called "custOrderid" and not "customerOrderId"
Either change the query or change the called parameter.
The query in the OrderedProduct class uses "customerOrderId"
http://netbeans.org/projects/samples/sources/samples-source-code/content/samples/javaee/AffableBean/src/java/entity/OrderedProduct.java