SpringBoot 1.5.3 createStoredProcedureQuery not accepting Null parameters - java

While using SpringBoot with MSSQL server stored proc, when the value is null, Stored proc fails to execute. the value have default as null while calling.
If the parameters are excluded, the proc works. But as these are optional parameters, what are my options to call the stored proc?
When i try to pass null while calling the stored procedure, it is failing with this error.
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: Error calling CallableStatement.getMoreResults; SQL [saveInfo]; nested exception is org.hibernate.exception.SQLGrammarException: Error calling CallableStatement.getMoreResults] with root cause
java.sql.SQLException: Parameter #1 has not been set.
at net.sourceforge.jtds.jdbc.TdsCore.executeSQL(TdsCore.java:1049)
at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQL(JtdsStatement.java:563)
at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.execute(JtdsPreparedStatement.java:787)
at org.hibernate.result.internal.OutputsImpl.<init>(OutputsImpl.java:52)
at org.hibernate.procedure.internal.ProcedureOutputsImpl.<init>(ProcedureOutputsImpl.java:32)
at org.hibernate.procedure.internal.ProcedureCallImpl.buildOutputs(ProcedureCallImpl.java:411)
at org.hibernate.procedure.internal.ProcedureCallImpl.getOutputs(ProcedureCallImpl.java:363)
at org.hibernate.jpa.internal.StoredProcedureQueryImpl.outputs(StoredProcedureQueryImpl.java:234)
at org.hibernate.jpa.internal.StoredProcedureQueryImpl.execute(StoredProcedureQueryImpl.java:217)
at com.tda.etfmc.service.repository.ETFMgmtRepository.saveCommissionFreeETF(ETFMgmtRepository.java:87)
at com.tda.etfmc.service.repository.ETFMgmtRepository$$FastClassBySpringCGLIB$$d1d68142.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
StoredProc:
CREATE PROCEDURE [dbo].[saveInfo]
#input1 varchar(16) = NULL,
#input2 varchar(16) = NULL
AS
BEGIN
//do save here
END
GO
#Repository
public class MyRepository {
private EntityManager entityManager;
public MyRepository(EntityManager entityManager) {
this.entityManager = entityManager;
}
#Procedure(name = "saveInfo")
#Transactional
public void saveInfo(List<Input> inputList) throws SQLException {
StoredProcedureQuery saveInfo;
for (Input input : inputList) {
saveInfo = entityManager.createNamedStoredProcedureQuery("saveInfo");
saveInfo.setParameter("input1", input.getInput1());// pass null here
saveInfo.setParameter("input2", input.getInput2());
saveInfo.execute();
}
}
}
#Data
#NamedStoredProcedureQuery(name = "saveInfo", procedureName = "saveInfo", parameters = {
#StoredProcedureParameter(name = "input1", type = String.class, mode = ParameterMode.IN),
#StoredProcedureParameter(name = "input2", type = String.class, mode = ParameterMode.IN) })
class Input implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name = "#input1")
private String input1;
#Column(name = "#input2")
private String input2;
}

Related

org.postgresql.util.PSQLException: ERROR: operator does not exist: character varying = bytea

I am trying to save and Excel file to my database. I get this error:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
org.postgresql.util.PSQLException: ERROR: operator does not exist: character varying = bytea
Hint: No operator matches the given name and argument types. You might need to add explicit type casts.
This is my controller post method:
#PostMapping
public ResponseEntity<DocumentCreateResponse> addDocument(#RequestParam("file") MultipartFile file) throws IOException {
Path copyLocation = Paths.get(uploadDir, Objects.requireNonNull(file.getOriginalFilename()));
Files.copy(file.getInputStream(), copyLocation, StandardCopyOption.REPLACE_EXISTING);
Document savedDocument = documentService.save(copyLocation.toAbsolutePath().toFile());
if (savedDocument == null){
return new ResponseEntity<>(new DocumentCreateResponse(null), null, HttpStatus.NOT_ACCEPTABLE);
}
return new ResponseEntity<>(new DocumentCreateResponse(savedDocument.getId()), null, HttpStatus.ACCEPTED);
}
This is document class:
#Entity
public class DocumentEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name ="document_id")
private Long id;
#Column(name ="document_file")
private File file;
public DocumentEntity() {
}
public DocumentEntity(File file) {
this.file = file;
}
}
And this is my schema creation file (I use Flyway and PostgreSQL)
create table if not exists document_entity
(
document_id bigserial
constraint document_entity_document_id
not null primary key,
document_file varchar not null
);
Where should I add change, to let my files save properly and not cause this error? I have read articles and seen this error, but I do not see what should I change in my code.
public class DocumentService implements DocumentServicePort {
private final DocumentRepository documentRepository;
public DocumentService(DocumentRepository documentRepository) {
this.documentRepository = documentRepository;
}
#Override
public Document save(File file) {
Document document = new Document(file);
if (document.hasValidExtension(document)) {
documentRepository.saveDocument(document);
return document;
}
return null;
}
}
You've declared your file as varchar in database, where in your application you've declared that field as File.
You can do a few things, but for the case you've mentioned, change the type of the column in database. It should be 'bytea`
run this on db (better if the table is empty):
ALTER TABLE document_entity ALTER COLUMN document_file TYPE bytea USING document_file::TEXT::BYTEA;

java.util.List.iterator() is no accessor method

When I am trying to access, List method iterator() i am getting below exception:
java.lang.IllegalArgumentException: Invoked method public abstract java.util.Iterator java.util.List.iterator() is no accessor method!
at org.springframework.util.Assert.notNull(Assert.java:115) ~[spring-core-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.data.projection.MapAccessingMethodInterceptor$Accessor.<init>(MapAccessingMethodInterceptor.java:97) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
at org.springframework.data.projection.MapAccessingMethodInterceptor.invoke(MapAccessingMethodInterceptor.java:62) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
at org.springframework.data.projection.ProjectingMethodInterceptor.invoke(ProjectingMethodInterceptor.java:75) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.data.projection.ProxyProjectionFactory$TargetAwareMethodInterceptor.invoke(ProxyProjectionFactory.java:218) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]
Code snippet below:
#RequestMapping (value = "/{field}", method = RequestMethod.PATCH, produces = "application/json")
#ResponseBody
public void applyPatchRequest(#PathVariable String field ,JsonArray operations) {
LookupPatchDto lookupPatchDto = new LookupPatchDto();
lookupPatchDto.setField(field);
lookupPatchDto.setVals(lookupValsService.getAllByField(field));
final JsonPatch patch = Json.createPatch(operations);
final JsonObject result = patch.apply(lookupPatchConverter.toJson(lookupPatchDto));
lookupPatchDto = lookupPatchConverter.fromJson(result);
lookupValsService.save(lookupPatchDto.getVals());
}
I am getting error on below line while applying apply function.
final JsonObject result = patch.apply(lookupPatchConverter.toJson(lookupPatchDto));

NonUniqueObjectException in Confluence with scheduled job

Got a huge problem with quartz Job in Confluence, regarding the page creation.
QUARTZ Job class:
#ComponentImport
private final SpaceManager spaceManager;
#Autowired
private final GeneralConfig config;
#Autowired
private final PageCreator pageCreator;
#ComponentImport
private final PageManager pageManager;
#Autowired
public ReportingPluginJob(GeneralConfig config, SpaceManager spaceManager, PageCreator pageCreator,
PageManager pageManager) {
this.config = config;
this.spaceManager = spaceManager;
this.pageCreator = pageCreator;
this.pageManager = pageManager;
}
private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(ReportingPluginJob.class);
#Override
public void execute(JobExecutionContext jec) throws JobExecutionException {
Collection<String> keys = spaceManager.getAllSpaceKeys(SpaceStatus.CURRENT);
String parentPageName = config.getSchedulerWeeklyParentPageName();
for (String key : keys) {
Page parentPage
= pageManager.getPage(key, parentPageName);
if (parentPage != null) {
LOG.debug("Creating weekly report for space " + key);
long pageId = parentPage.getId();
try {
pageCreator.createEazyBiReport(key, pageId);
} catch (ApplicationException e) {
LOG.error("FAILED TO CREATE A REPORT FOR SPACE " + key + " with error: " + System.lineSeparator()
+ e.getMessage());
}
}
}
}
PAGE CREATION class:
Space space = spaceManager.getSpace(spaceKey);
if (page != null) {
page.setTitle(pageTitle);
page.setSpace(space);
page.setVersion(1);
page.addLabelling(new Labelling(label, page.getEntity(), AuthenticatedUserThreadLocal.get()));
page.setCreator(AuthenticatedUserThreadLocal.get());
page.setCreationDate(new Date());
Page parent = pageManager.getPage(parentId);
if (parent != null) {
parent.addChild(page);
}
}
pageManager.saveContentEntity(page, DefaultSaveContext.builder().suppressNotifications(true).build());
attachmentProvider.attachExcelFileToPage(page);
AND Finally the exception which is driving me mad:
org.springframework.dao.DuplicateKeyException: A different object with the same identifier value was already associated with the session : [com.atlassian.confluence.spaces.Space#31653891]; nested exception is org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [com.atlassian.confluence.spaces.Space#31653891]
at org.springframework.orm.hibernate5.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:259)
at org.springframework.orm.hibernate5.HibernateTemplate.doExecute(HibernateTemplate.java:362)
at org.springframework.orm.hibernate5.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:326)
at org.springframework.orm.hibernate5.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:704)
at com.atlassian.confluence.core.persistence.hibernate.HibernateObjectDao.saveRaw(HibernateObjectDao.java:207)
at com.atlassian.confluence.pages.persistence.dao.hibernate.CachingPageDao.saveRaw(CachingPageDao.java:157)
at com.atlassian.confluence.core.DefaultContentEntityManager.saveContentEntity(DefaultContentEntityManager.java:150)
at com.atlassian.confluence.pages.DefaultPageManager.saveContentEntity(DefaultPageManager.java:1388)
at sun.reflect.GeneratedMethodAccessor2132.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at com.atlassian.spring.interceptors.SpringProfilingInterceptor.invoke(SpringProfilingInterceptor.java:16)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at com.atlassian.confluence.util.profiling.ConfluenceMonitoringMethodInterceptor.invoke(ConfluenceMonitoringMethodInterceptor.java:34)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy105.saveContentEntity(Unknown Source)
at sun.reflect.GeneratedMethodAccessor2132.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.atlassian.plugin.util.ContextClassLoaderSettingInvocationHandler.invoke(ContextClassLoaderSettingInvocationHandler.java:26)
at com.sun.proxy.$Proxy253.saveContentEntity(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
at org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.doInvoke(ServiceInvoker.java:56)
at org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.invoke(ServiceInvoker.java:60)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.eclipse.gemini.blueprint.service.util.internal.aop.ServiceTCCLInterceptor.invokeUnprivileged(ServiceTCCLInterceptor.java:70)
at org.eclipse.gemini.blueprint.service.util.internal.aop.ServiceTCCLInterceptor.invoke(ServiceTCCLInterceptor.java:53)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.eclipse.gemini.blueprint.service.importer.support.LocalBundleContextAdvice.invoke(LocalBundleContextAdvice.java:57)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy2863.saveContentEntity(Unknown Source)
at com.censored.atlassian.plugins.service.PageCreator.createEazyBiReport(PageCreator.java:128)
at com.censored.atlassian.plugins.service.ReportingPluginJob.execute(ReportingPluginJob.java:64)
at com.atlassian.confluence.plugin.descriptor.JobModuleDescriptor$DelegatingPluginJob.lambda$execute$0(JobModuleDescriptor.java:113)
at com.atlassian.confluence.impl.vcache.VCacheRequestContextManager.doInRequestContextInternal(VCacheRequestContextManager.java:87)
at com.atlassian.confluence.impl.vcache.VCacheRequestContextManager.doInRequestContext(VCacheRequestContextManager.java:71)
at com.atlassian.confluence.plugin.descriptor.JobModuleDescriptor$DelegatingPluginJob.execute(JobModuleDescriptor.java:112)
at org.quartz.core.JobRunShell.run(JobRunShell.java:223)
at com.atlassian.confluence.schedule.quartz.ConfluenceQuartzThreadPool.lambda$runInThread$0(ConfluenceQuartzThreadPool.java:16)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549)
According the stack trace, I've got a problem during the page save (saveContentEntity). It seems, the page save needs to update a space associated with the page too.
And here comes the problem. According to the stack trace, this space exists in the Hibernate session already. evict and clear of the actual session does not work.
Any suggestions, how can I handle this exception, or how can I actually remove the space from Hibernate session?
Apparently, this is what's happening in your code:
Within your SpaceManager, your session finds a Session object with ID 1 (assume that) and returns it.
Your method uses this reference to associate with another object, a Page one.
And finally, your PageManager persist this data in the database.
Probably, your problem is problem that:
From step 1 to 2, when the SpaceManager returns the data, your transaction is ended and your returned object becomes detached.
After that, when you call save, you are trying to persist a detached Session, but it already exists in the database. Then you get an exception.
You could try to use the merge method or remove the cascade from this reference in your entity.
(Please provide your entity code so I can improve my answer if there's anything wrong or which don't work for you.)
We ran into the same problem and what solved it for us was to put the code that creates the page (and loads other objects, like the space or the parent page) all into a transaction:
private void createNewPage(String title, String pageInput, Long parentPageId, String spaceKey) {
transactionTemplate.execute(() -> {
Page page = new Page();
page.setTitle(title);
page.setBodyAsString(pageInput);
Space space = spaceManager.getSpace(spaceKey);
page.setSpace(space);
Page parentPage = pageManager.getPage(parentPageId);
if (parentPage != null) {
page.setParentPage(parentPage);
parentPage.addChild(page);
}
pageManager.saveContentEntity(page, DefaultSaveContext.DEFAULT);
return null;
});
}
com.atlassian.sal.api.transaction.TransactionTemplate can be injected with #ComponentImport

Need to call StoredProcedure in jave using Hibernate

Just want to call Stored procedure of SQL server from java using Hibernate as ORM.
The stored Procedure has so many result set which I am keeping it in Java as DTO's and each one as list in one DTO to send as JSON payload for Front-end integration.
But I am getting exception saying"org.hibernate.MappingException: Unknown entity: com.test.plans.dto.TemplatesDTO"
public ItemDetailsDTO getItemDetails(int no) {
Session session = getSession();
Connection connection = null;
List<ItemDetailsDTO> resultList = new ArrayList<>();
try {
ResultSet rs = null;
SessionImpl sessionImpl = (SessionImpl) session;
connection = sessionImpl.connection();
Query query = session.createSQLQuery("exec usp_GetItemDetails :no")
.addEntity(TemplatesDTO.class)
.setParameter("no", no);
resultList = query.list();
} catch (Exception e) {
System.out.println("error");
e.printStackTrace();
}
return resultList.get(0);
}
DTO :
import java.util.List;
public class ItemDetailsDTO {
private List<TemplatesDTO> templates;
public List<TemplatesDTO> gettemplates() {
return templates;
}
public void settemplates(List<TemplatesDTO> templates) {
this.templates = templates;
}
}
Please find below complete trace of exception
org.hibernate.MappingException: Unknown entity: com.test.plans.dto.TemplatesDTO
at org.hibernate.internal.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:783)
at org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.getSQLLoadable(SQLQueryReturnProcessor.java:358)
at org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.processRootReturn(SQLQueryReturnProcessor.java:411)
at org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.processReturn(SQLQueryReturnProcessor.java:378)
at org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.process(SQLQueryReturnProcessor.java:180)
at org.hibernate.loader.custom.sql.SQLCustomQuery.(SQLCustomQuery.java:71)
at org.hibernate.engine.query.internal.NativeQueryInterpreterStandardImpl.createQueryPlan(NativeQueryInterpreterStandardImpl.java:70)
at org.hibernate.engine.query.spi.QueryPlanCache.getNativeSQLQueryPlan(QueryPlanCache.java:210)
at org.hibernate.internal.AbstractSessionImpl.getNativeSQLQueryPlan(AbstractSessionImpl.java:306)
at org.hibernate.internal.AbstractSessionImpl.list(AbstractSessionImpl.java:322)
at org.hibernate.internal.SQLQueryImpl.list(SQLQueryImpl.java:125)
at nbcu.compass.contingencyplans.dao.impl.ContDAOImpl.getItemDetails(ContingencyDAOImpl.java:503)
at nbcu.compass.contingencyplans.dao.impl.ContDAOImpl$$FastClassBySpringCGLIB$$c2b97106.invoke()
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
at com.test.plans.dao.impl.ContDAOImpl$$EnhancerBySpringCGLIB$$a1741e1f.getItemDetails()
at com.test.plans.service.impl.ContPlanServiceImpl.getConditionScheduleItemDetails(ContingencyPlanServiceImpl.java:316)
at test.plans.plans.rest.impl.PlanResourceImpl.getItemDetails(PlanResourceImpl.java:87)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)

Spring, Hibernate : Database call complete for saving object, yet returns null value sometimes

I am working on a Spring-MVC appplication with Hibernate and PostgreSQL in which these days we are experiencing a very strange problem. Sometimes when an object is being persisted, I am returning it's ID from the DAO layer to the service layer. This ID is then being broadcasted via our PUSH framework, after which point the object is retrieved by a call. At this point I am getting a NPE, although the object is saved, primary-key ID is non-zero, session is also flushed before returning the ID. What might be going wrong?
Example :
#Override
public void addNestedGroupNoteComment(String commentText, int noteId, int commentId){
int saveId = this.groupNoteHistoryDAO.addGroupNoteComment(groupNoteHistory, noteId);
if(saveId!=0) {
notification.setCommentId(saveId);
this.chatService.sendNotification(notification, groupMembers.getMemberid());
}
DAO method :
#Repository
#Transactional
public class GroupNoteHistoryDAOImpl implements GroupNoteHistoryDAO {
private final SessionFactory sessionFactory;
#Autowired
public GroupNoteHistoryDAOImpl(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
#Override
public int addGroupNoteComment(GroupNoteHistory noteHistory, int noteId) {
Session session = this.sessionFactory.getCurrentSession();
GroupNotes notes = (GroupNotes) session.get(GroupNotes.class, noteId);
if(notes!=null) {
notes.getGroupNoteHistorySet().add(noteHistory);
noteHistory.setMhistory(notes);
int saveId = (Integer) session.save(noteHistory);
session.flush();
return saveId;
}
}
}
Now, after broadcasting the ID, this method is called :
#Override
public GroupNoteHistory getGroupNoteHistoryById(int historyId) {
GroupNoteHistory groupNoteHistory = this.groupNoteHistoryDAO.getGroupNoteHistoryById(historyId);
// Above object is many times null, tried System.out, it was with non-zero values.
}
DAO method :
#Override
public GroupNoteHistory getGroupNoteHistoryById(int historyId) {
Session session = this.sessionFactory.getCurrentSession();
return (GroupNoteHistory) session.get(GroupNoteHistory.class, historyId);
}
Any thoughts?
Update
Error log :
HTTP Status 500 - Request processing failed; nested exception is java.lang.NullPointerException
type Exception report
message Request processing failed; nested exception is java.lang.NullPointerException
description The server encountered an internal error that prevented it from fulfilling this request.
exception
root cause
java.lang.NullPointerException
com.project_name.spring.service.GroupNoteHistoryServiceImpl.getGroupNoteHistoryById(GroupNoteHistoryServiceImpl.java:156)
sun.reflect.GeneratedMethodAccessor647.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
Here int saveId = this.groupNoteHistoryDAO.addGroupNoteComment(groupNoteHistory, noteId); you already have a GroupeNoteHistory.
After this you manipulate it and save it
noteHistory.setMhistory(notes);
int saveId = (Integer) session.save(noteHistory);
session.flush();
return saveId;`
So you must check if the GroupNoteHistory already exists and is not null before using it. That's why you get a NPE.
Finally this worked for me :
#Override
public int addGroupNoteComment(GroupNoteHistory noteHistory, int noteId) {
Session session = this.sessionFactory.openSession();
try {
session.beginTransaction();
GroupNotes notes = (GroupNotes) session.get(GroupNotes.class, noteId);
if(notes!=null) {
notes.getGroupNoteHistorySet().add(noteHistory);
noteHistory.setMhistory(notes);
session.save(noteHistory);
session.flush();
session.getTransaction().commit();
return noteHistory.getMhistoryid();
}
} catch (Exception e) {
e.printStackTrace();
}finally {
session.close();
}
return 0;
}

Categories