gson.toJson() throws StackOverflowError and I dont have a circular dependency - spring-boot

I am trying to generate a JSON
Gson gson = new Gson();
String json = gson.toJson(item);
But every time i try to I keep getting a stackoverflow error:
java.lang.StackOverflowError: null
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239)
at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:968)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:112)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:112)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239)
at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:968)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:112)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239)
It is caused when i try to convert DataTableResults class which contains a list of Transactions.class as its property field to a string.
The DataTableResult class looks like this :
public class DataTableResults<T> {
/** The draw. */
private String draw;
/** The records filtered. */
private String recordsFiltered;
/** The records total. */
private String recordsTotal;
/** The list of data objects. */
#SerializedName("data")
List<T> listOfDataObjects;
/**
* Gets the draw.
*
* #return the draw
*/
public String getDraw() {
return draw;
}
/**
* Sets the draw.
*
* #param draw the draw to set
*/
public void setDraw(String draw) {
this.draw = draw;
}
/**
* Gets the records filtered.
*
* #return the recordsFiltered
*/
public String getRecordsFiltered() {
return recordsFiltered;
}
/**
* Sets the records filtered.
*
* #param recordsFiltered the recordsFiltered to set
*/
public void setRecordsFiltered(String recordsFiltered) {
this.recordsFiltered = recordsFiltered;
}
/**
* Gets the records total.
*
* #return the recordsTotal
*/
public String getRecordsTotal() {
return recordsTotal;
}
/**
* Sets the records total.
*
* #param recordsTotal the recordsTotal to set
*/
public void setRecordsTotal(String recordsTotal) {
this.recordsTotal = recordsTotal;
}
/**
* Gets the list of data objects.
*
* #return the listOfDataObjects
*/
public List<T> getListOfDataObjects() {
return listOfDataObjects;
}
/**
* Sets the list of data objects.
*
* #param listOfDataObjects the listOfDataObjects to set
*/
public void setListOfDataObjects(List<T> listOfDataObjects) {
this.listOfDataObjects = listOfDataObjects;
}
}
while the Transactions.class looks like this
#Entity
#Table(name = "TRANS")
public class Transactions extends DefaultEntity {
public enum TRANSACTIONTYPE{WITHDRAW, DEPOSIT, WIN, LOSS}
#ManyToOne(targetEntity = User.class)
#JoinColumn(name="player")
private User player;
private double amount;
#Enumerated(EnumType.STRING)
private TRANSACTIONTYPE transactiontype;
private String referenceID;
private String detail;
private String token;
public TRANSACTIONTYPE getTransactiontype() {
return transactiontype;
}
public Transactions setTransactiontype(TRANSACTIONTYPE transactiontype) {
this.transactiontype = transactiontype;
return this;
}
public double getAmount() {
return amount;
}
public Transactions setAmount(double amount) {
this.amount = amount;
return this;
}
public String getReferenceID() {
return referenceID;
}
public Transactions setReferenceID(String referenceID) {
this.referenceID = referenceID;
return this;
}
public String getDetail() {
return detail;
}
public Transactions setDetail(String detail) {
this.detail = detail;
return this;
}
public String getToken() {
return token;
}
public Transactions setToken(String token) {
this.token = token;
return this;
}
public User getPlayer() {
return player;
}
public Transactions setPlayer(User player) {
this.player = player;
return this;
}
}
according to this post, it is supposed to be caused by a circular dependency, but in my case it is not cause i dont have one. What else could cause such error ?

You should remove extends DefaultEntity, you don't need it and may bring circular dependency.
Also you have a #ManyToOne relationship with User, that may cause circular dependency if User also have a reference to Transactions.
If you have it in both parts, you should exclude it from serialization with transient on one part at least.

Related

Repository returns empty list in Spring boot

I am trying to write a simple REST to pull records from a table that was shared with me. Since the table doesn't have a default ID column, I embedded a pk column to the entity object. Please find the code below for your review.
The issue I'm facing is that the repository.findByMediaType, where mediaType is one of the entity properties, returns empty list. I made sure the query param is not null and there are records in the table for the param passed. I tried findAll as well but didn't work. I can't seem to find what's wrong with the code. I am new to spring boot and would like to know the different ways I can debug this.
Service implementation class
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.hyb.enterprisedashboard.api.entity.Tenders;
import com.hyb.enterprisedashboard.api.repository.DashboardRepository;
#Service
public class DashboardServiceImpl implements DashboardService{
Logger logger = LoggerFactory.getLogger(DashboardServiceImpl.class);
#Autowired
DashboardRepository dashboardRepository;
#Override
public List<Tenders> getTenderByMediaType(String mediaType) {
List<Tenders> tenderList = dashboardRepository.findAll();
//findByMediaType(mediaType);
tenderList.stream().forEach(tender -> {
logger.info("Order {} paid via {}",tender.getId().getOrderNumber(), tender.getMediaType());
});
return tenderList;
}
}
Entity class
import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
#Entity
#Table(name = "TENDERS")
public class Tenders {
/** The id. */
#EmbeddedId
private TendersPK id;
/** The dateTime. */
#Column(name="DATE_TIME")
private Date dateTime;
/** The tenderMedia. */
#Column(name="TENDERED_MEDIA")
private String tenderMedia;
/** The mediaType. */
#Column(name="MEDIA_TYPE")
private String mediaType;
/** The tenderAmount. */
#Column(name="TENDERED_AMOUNT")
private BigDecimal tenderAmount;
/**
* #return the id
*/
public TendersPK getId() {
return id;
}
/**
* #param id the id to set
*/
public void setId(TendersPK id) {
this.id = id;
}
/**
* #return the dateTime
*/
public Date getDateTime() {
return dateTime;
}
/**
* #param dateTime the dateTime to set
*/
public void setDateTime(Date dateTime) {
this.dateTime = dateTime;
}
/**
* #return the tenderMedia
*/
public String getTenderMedia() {
return tenderMedia;
}
/**
* #param tenderMedia the tenderMedia to set
*/
public void setTenderMedia(String tenderMedia) {
this.tenderMedia = tenderMedia;
}
/**
* #return the mediaType
*/
public String getMediaType() {
return mediaType;
}
/**
* #param mediaType the mediaType to set
*/
public void setMediaType(String mediaType) {
this.mediaType = mediaType;
}
/**
* #return the tenderAmount
*/
public BigDecimal getTenderAmount() {
return tenderAmount;
}
/**
* #param tenderAmount the tenderAmount to set
*/
public void setTenderAmount(BigDecimal tenderAmount) {
this.tenderAmount = tenderAmount;
}
#Override
public String toString() {
return "Tenders [id=" + id + ", dateTime=" + dateTime + ", tenderMedia=" + tenderMedia + ", mediaType="
+ mediaType + ", tenderAmount=" + tenderAmount + "]";
}
}
PK Embedded class
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
#Embeddable
public class TendersPK implements Serializable{
/** The Constant serialVersionUID.*/
private static final long serialVersionUID = 1L;
/**
*
*/
public TendersPK() {
}
/**
* #param storeNumber
* #param orderNumber
*/
public TendersPK(long storeNumber, long orderNumber) {
super();
this.storeNumber = storeNumber;
this.orderNumber = orderNumber;
}
#Column(name = "STORE_NUMBER")
private long storeNumber;
#Column(name = "ORDER_NUMBER")
private long orderNumber;
/**
* #return the storeNumber
*/
public long getStoreNumber() {
return storeNumber;
}
/**
* #param storeNumber the storeNumber to set
*/
public void setStoreNumber(long storeNumber) {
this.storeNumber = storeNumber;
}
/**
* #return the orderNumber
*/
public long getOrderNumber() {
return orderNumber;
}
/**
* #param orderNumber the orderNumber to set
*/
public void setOrderNumber(long orderNumber) {
this.orderNumber = orderNumber;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (orderNumber ^ (orderNumber >>> 32));
result = prime * result + (int) (storeNumber ^ (storeNumber >>> 32));
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof TendersPK))
return false;
TendersPK other = (TendersPK) obj;
if (orderNumber != other.orderNumber)
return false;
if (storeNumber != other.storeNumber)
return false;
return true;
}
#Override
public String toString() {
return "TendersPK [storeNumber=" + storeNumber + ", orderNumber=" + orderNumber + "]";
}
}
Repository class
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.hyb.enterprisedashboard.api.entity.Tenders;
import com.hyb.enterprisedashboard.api.entity.TendersPK;
#Repository
public interface DashboardRepository extends JpaRepository<Tenders, TendersPK>{
#Query("select t from Tenders t where t.mediaType = ?1")
List<Tenders> findByMediaType(String mediaType);
}
And I see the below query passed in the console
Hibernate: select tenders0_.order_number as order_number1_0_, tenders0_.store_number as store_number2_0_, tenders0_.date_time as date_time3_0_, tenders0_.media_type as media_type4_0_, tenders0_.tendered_amount as tendered_amount5_0_, tenders0_.tendered_media as tendered_media6_0_ from tenders tenders0_
Could anyone please help to find the cause?
This was happening to me and it turns out my spring.datasource.* properties were not being set. I had them in the wrong file and the were not being read.
I would think that my repository query would error out if I had not provided datasource url, username, and password - instead I would simply just get an empty list returned.
I ended up figuring out that I was not pulling my datasource credentials by adding this in my RestController:
#Value("${spring.datasource.username}")
String username;
Then I just printed username to the system.out.println. When starting the application I would get an error that spring.datasource.username was undefined. Hence I knew I was not loading datasource information that I thought I was.

What are the best practice for audit log(user activity) in micro-services?

In our microservice architecture, we are logging user-activity to mongo database table? Is there any good way to store and retrieve audit log?
You can think of a solution something similar to the below by storing AuditLogging into the Mongo db by using DAO pattern.
#Entity
#Table(name = "AuditLogging")
public class AuditLogging implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "auditid", updatable = false, nullable = false)
private Long auditId;
#Column(name = "event_type", length = 100)
#Enumerated(EnumType.STRING)
private AuditingEvent event;
#Column(name = "event_creator", length = 100)
#Enumerated(EnumType.STRING)
private EventCreator eventCreator;
#Column(name = "adminid", length = 20)
private String adminId;
#Column(name = "userid", length = 20)
private String userId;
#Column(name = "event_date")
private Date eventDate;
}
public class Constants {
public static final String EVENT_TYPE = "eventType";
public static final String EVENT_CREATOR = "eventCreator";
public static final String NEW_EMAIL_ID = "newEmailId";
public static final String OLD_EMAIL_ID = "oldEmailId";
}
public enum AuditEvent {
USER_REGISTRATION,
USER_LOGIN,
USER_LOGIN_FAIL,
USER_ACCOUNT_LOCK,
USER_LOGOFF,
USER_PASSWORD_CHANGE,
USER_PASSWORD_CHANGE_FAIL,
USER_FORGOT_PASSWORD,
USER_FORGOT_PASSWORD_FAIL,
ADMIN_LOGIN
}
public enum EventCreator {
ADMIN_FOR_SELF,
USER_FOR_SELF,
ADMIN_FOR_USER
}
public interface AuditingDao {
/**
* Stores the event into the DB/Mongo or Whatever
*
* #param auditLogging
* #return Boolean status
*/
Boolean createAuditLog(final AuditLogging auditLogging);
/* Returns the log occurrence of a specific event
*
* #param event
* #return List of logged events by type
*/
List<AuditLogging> getLogsForEvent(final AuditingEvent event);
}
public interface AuditingService {
/**
* Creates an Audit entry in the AuditLogging table using the
* DAO layer
*
* #param auditingEvent
* #param eventCreator
* #param userId
* #param adminId *
* #return {#link Boolean.TRUE} for success and {#link Boolean.FALSE} for
* failure
*/
Boolean createUserAuditEvent(final AuditEvent auditEvent,
final EventCreator eventCreator, final String userId, final String adminId,
final String newEmailId,final String oldEmailId);
/**
*
* Returns all event for a user/admin based on the id
*
* #param id
* #return List of logged events for an id
*/
List<AuditLogging> fetchLoggedEventsById(final String id);
/***
* Returns all event based on event type
*
* #param eventName
* #return List of logged events for an event
*/
List<AuditLogging> fetchLoggedEventsByEventName(final String eventName);
}
#Service("auditingService")
public class AuditServiceImpl implements AuditingService {
#Autowired
private AuditingDao auditingDao;
private static Logger log = LogManager.getLogger();
#Override
public Boolean createUserAuditingEvent(AuditEvent auditEvent,
EventCreator eventCreator, String userId, String adminId,
String newEmailId,String oldEmailId) {
AuditLogging auditLogging = new AuditLogging();
auditLogging.setEvent(auditingEvent);
auditLogging.setEventCreator(eventCreator);
auditLogging.setUserId(userId);
auditLogging.setAdminId(adminId);
auditLogging.setEventDate(new Date());
return Boolean.TRUE;
}
#Override
public List<AuditLogging> fetchLoggedEventsByEventName(
final String eventName) {
AuditEvent event = null;
try {
event = AuditingEvent.valueOf(eventName);
} catch (Exception e) {
log.error(e);
return Collections.emptyList();
}
return auditingDao.getLogsForEvent(event);
}
public void setAuditingDao(AuditingDao auditingDao) {
this.auditingDao = auditingDao;
}
}
Writing an aspect is always good for this type of scenarios by pointing to the appropriate controller method to trigger the event.
#Aspect
#Component("auditingAspect")
public class AuditingAspect {
#Autowired
AuditingService auditingService;
/* The below controllers you can think of your microservice endpoints
*/
#Pointcut("execution(* com.controller.RegistrationController.authenticateUser(..)) ||execution(* com.controller.RegistrationController.changeUserPassword(..)) || execution(* com.controller.RegistrationController.resetPassword(..)) ||execution(* com.controller.UpdateFunctionalityController.updateCustomerDetails(..))")
public void aroundPointCut() {}
#Around("aroundPointCut()")
public Object afterMethodInControllerClass(ProceedingJoinPoint joinPoint)
throws Throwable {
joinPoint.getSignature().getName();
joinPoint.getArgs();
// auditingService
Object result = joinPoint.proceed();
ResponseEntity entity = (ResponseEntity) result;
HttpServletRequest request =
((ServletRequestAttributes) RequestContextHolder
.getRequestAttributes()).getRequest();
if(!((request.getAttribute(Constants.EVENT_TYPE).toString()).equalsIgnoreCase(AuditEvent.USER_LOGIN.toString()) || (((request.getAttribute(Constants.EVENT_TYPE).toString()).equalsIgnoreCase(AuditEvent.ADMIN_LOGIN.toString()))))){
auditingService.createUserAuditEvent(
(AuditingEvent) request.getAttribute(Constants.EVENT_TYPE),
(EventCreator) request.getAttribute(Constants.EVENT_CREATOR),
(request.getAttribute(Constants.USER_ID)!= null ? request.getAttribute(Constants.USER_ID).toString():""), null,
(request.getAttribute(Constants.NEW_EMAIL_ID) == null ? ""
: request.getAttribute(Constants.NEW_EMAIL_ID).toString()),
(request.getAttribute(Constants.OLD_EMAIL_ID) == null ? ""
: request.getAttribute(Constants.OLD_EMAIL_ID).toString()));
}
return entity;
}
}
From the REST controller the Aspect will be triggered when it finds the corresponding event.
#RestController
public class RegistrationController {
#RequestMapping(path = "/authenticateUser", method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
/* This method call triggers the aspect */
#ResponseBody
public ResponseEntity<String> authenticateUser(HttpServletRequest request, #RequestBody User user)
throws Exception {
request.setAttribute(Constants.EVENT_TYPE, AuditingEvent.USER_LOGIN);
request.setAttribute(Constants.EVENT_CREATOR, EventCreator.USER_FOR_SELF);
request.setAttribute(Constants.USER_ID, user.getUserId());
ResponseEntity<String> responseEntity = null;
try {
// Logic for authentication goes here
responseEntity = new ResponseEntity<>(respData, HttpStatus.OK);
} catch (Exception e) {
request.setAttribute(Constants.EVENT_TYPE, AuditEvent.USER_LOGIN_FAIL);
responseEntity = new ResponseEntity<>(respData, HttpStatus.INTERNAL_SERVER_ERROR);
}
return responseEntity;
}
}
I hope this answer make sense and you can implement similar functionality for Mongo as well.
Cheers !

Calling stored function in hibernate

I have tried multiple ways to call stored function in hibernate---
1) Via Session.doWork callback method
session.doWork(new Work() {
#Override
public void execute(Connection conn)
throws SQLException {
CallableStatement stmt = conn.prepareCall("{? = call test(?)}");
stmt.registerOutParameter(1, Types.INTEGER);
stmt.setString(2, "callIndex");
stmt.execute();
eventVal = stmt.getInt(1);
}
});
This works fine but cannot return any thing from here, so doesn't solve my purpose.
2) Via Native query
StringBuilder query = new StringBuilder();
query.append("Select test() from dual");
SQLQuery sqlQuery = session.createSQLQuery(query.toString());
List resultList = sqlQuery.list();
events = new ArrayList<Events>();
Object result = null;
if (events != null && !events.isEmpty()) {
for (int i = 0; i < events.size(); i++) {
result = resultList.get(i);
}
}
This doesn't work and gives me some No Dialect mapping for JDBC type -10, not sure of the reason.
3) Via named query
My entity class is ---
#NamedNativeQueries({
#NamedNativeQuery(name = "testCall",
query = "? = call test()",
hints = {#QueryHint(name = "org.hibernate.callable", value = "true" )},
resultClass = Events.class
)
})
#Entity
#Table(name = "EVENTS")
public class Events implements Serializable {
private static final long serialVersionUID = -24850323296832289L;
/** The id. */
#Id
#Column(name = "EVENT_SID")
private Integer eventId;
/** The processed status. */
#Column(name = "EVENT_STATUS")
private String eventStatus;
/** The event type. */
#Column(name = "EVENT_TYPE_NAME")
private String eventType;
/** The live event. */
#Column(name = "IS_LIVE_EVENT")
private Integer liveEvent;
/** The event message. */
#Lob
#Column(name = "EVENT_MESSAGE")
private String eventMessage;
public Integer getEventId() {
return eventId;
}
public void setEventId(Integer eventId) {
this.eventId = eventId;
}
public String getEventStatus() {
return eventStatus;
}
public void setEventStatus(String eventStatus) {
this.eventStatus = eventStatus;
}
/**
* Gets the event type.
*
* #return the event type
*/
public String getEventType() {
return eventType;
}
/**
* Sets the event type.
*
* #param eventType
* the new event type
*/
public void setEventType(String eventType) {
this.eventType = eventType;
}
/**
* Gets the live event.
*
* #return the live event
*/
public Integer getLiveEvent() {
return liveEvent;
}
/**
* Sets the live event.
*
* #param liveEvent
* the new live event
*/
public void setLiveEvent(Integer liveEvent) {
this.liveEvent = liveEvent;
}
/**
* Gets the event message.
*
* #return the event message
*/
public String getEventMessage() {
return eventMessage;
}
/**
* Sets the event message.
*
* #param eventMessage
* the new event message
*/
public void setEventMessage(String eventMessage) {
this.eventMessage = eventMessage;
}
}
The DAO through which I am making call have method ---
public Integer callSqlBlock(){
int event = 0;
Session session = getHibernateTemplate().getSessionFactory().getCurrentSession();
List<Events> events = null;
events = session.getNamedQuery("testCall").list();
return events.get(0).getEventId();
}
stored function on the DB end ---
create or replace
function test return SYS_REFCURSOR
as
p_order_recordset SYS_REFCURSOR;
begin
open p_order_recordset FOR SELECT EVENT_SID,EVENT_STATUS,EVENT_TYPE_NAME,IS_LIVE_EVENT FROM events;
return p_order_recordset;
end ;
execution of stored function via named query is giving me invalid column index
Please let me know where I am going wrong on this, and if possible please provide some example also

Spring/initBinder - Not able to get the value binded when multiple values are selected

The below code works fine when I try to save a single value of miniApple. I can see the value of miniApple object value in argument of controller i.e., apple. However I am not able to binder if there are multiple values. Not sure what should be the syntax to write inside the initBinder method for converting the string (comma separated value) into List of custom objects(here List of MiniApple)
When I select multiple values, I can the text value in setAsText() as comma separated values( eg: "miniApple1, miniApple2,miniAPlle3")
Controller method save()
public ModelAndView save(#ModelAttribute("Apple") Apple apple, BindingResult result, SessionStatus status) {
}
Init Binder method
#InitBinder
public void initBinder(WebDataBinder dataBinder) {
dataBinder.registerCustomEditor(MiniApple.class, new MiniAppleEditor(this.miniAppleService, true));
}
Custom Editor class with setAsText method
public class MiniAppleEditor extends PropertyEditorSupport {
/** The mini apple service. */
private final MiniAppleService miniAppleService;
/** Whether or not to allow null values. */
private boolean allowEmpty;
/**
* #param miniAppleService the miniAppleService to set
*/
public MiniAppleEditor(MiniAppleService miniAppleService) {
this(miniAppleService, false);
}
/**
* #param miniAppleService the miniAppleService to set
* #param allowEmpty indicates to allow empty mini apple.
*/
public MiniAppleEditor(MiniAppleService miniAppleService, boolean allowEmpty) {
this.miniAppleService = miniAppleService;
this.allowEmpty = allowEmpty;
}
/**
* #param text the id representing the MiniApple object.
*/
#Override
public void setAsText(String text) {
if (allowEmpty && !StringUtils.hasLength(text)) {
setValue(null);
} else {
setValue(miniAppleService.getMiniApple(Integer.parseInt(text)));
}
}
/**
* #return the Id as a String
*/
#Override
public String getAsText() {
MiniApple miniApple = (MiniApple) getValue();
if (miniApple == null) {
return "";
} else {
return miniApple.getAppleName();
}
}
}
Object which will get the values binded as an argument of controller save () method
#Entity
#Table("tbl_apple")
public class Apple implements Serializable {
private MiniApple miniApple;
getter/setter;
}

Jedis and JOhm Error

I am using Redis installed on Windows via chocolatey and setup jedis and JOhm in java project. The Redis server is live Redis version 2.6 When I want to save a Java object like the one in the post I got an error message.
java.lang.NoSuchMethodError: redis.clients.jedis.Jedis.sadd(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Long;
at redis.clients.johm.Nest.sadd(Nest.java:168)
at redis.clients.johm.JOhm.save(JOhm.java:220)
at redis.clients.johm.JOhm.save(JOhm.java:146)
This is my java object:
/**
*
*/
package com.smsgh.unitysmpp.MessageProcessor;
import java.io.Serializable;
import org.joda.time.DateTime;
import redis.clients.johm.Attribute;
import redis.clients.johm.Id;
import redis.clients.johm.Model;
/**
* #author Arsene Tochemey GANDOTE This class holds the Messages that needs a
* Delivery Receipt
*/
#Model
public class StoredShortMessage implements Serializable {
/**
*
*/
private static final long serialVersionUID = 6185862961624213864L;
#Id
private Integer id;
// session Id
#Attribute
private Long smppSessionId;
// Message Id
#Attribute
private String messageId;
// ESME Account Number#
#Attribute
private Long accountNumber;
// ESME Account Id
#Attribute
private String accountId;
// ESME API Pub Key
#Attribute
private String apiPublicKey;
// Message state
#Attribute
private String messageState;
// Network Error
#Attribute
private String networkErrorCode;
// First 20 Characters of the message
#Attribute
private String mesgFirstLines;
// esme TCP/IP connection
#Attribute
private String ip;
// message submitted datetime
#Attribute
private DateTime submitDate;
// final state date
#Attribute
private DateTime doneDate;
// source address
#Attribute
private byte srcTon;
#Attribute
private byte srcNpi;
#Attribute
private String srcAddr;
// destination address
#Attribute
private byte destTon;
#Attribute
private byte destNpi;
#Attribute
private String destAddr;
// delivery state
#Attribute
private char dlrState;
/**
*
*/
public StoredShortMessage() {
}
/**
* #return the smppSessionId
*/
public Long getSmppSessionId() {
return smppSessionId;
}
/**
* #param smppSessionId
* the smppSessionId to set
*/
public void setSmppSessionId(Long smppSessionId) {
this.smppSessionId = smppSessionId;
}
/**
* #return the messageId
*/
public String getMessageId() {
return messageId;
}
/**
* #param messageId
* the messageId to set
*/
public void setMessageId(String messageId) {
this.messageId = messageId;
}
/**
* #return the accountNumber
*/
public Long getAccountNumber() {
return accountNumber;
}
/**
* #param accountNumber
* the accountNumber to set
*/
public void setAccountNumber(Long accountNumber) {
this.accountNumber = accountNumber;
}
/**
* #return the accountId
*/
public String getAccountId() {
return accountId;
}
/**
* #param accountId
* the accountId to set
*/
public void setAccountId(String accountId) {
this.accountId = accountId;
}
/**
* #return the apiPublicKey
*/
public String getApiPublicKey() {
return apiPublicKey;
}
/**
* #param apiPublicKey
* the apiPublicKey to set
*/
public void setApiPublicKey(String apiPublicKey) {
this.apiPublicKey = apiPublicKey;
}
/**
* #return the messageState
*/
public String getMessageState() {
return messageState;
}
/**
* #param messageState
* the messageState to set
*/
public void setMessageState(String messageState) {
this.messageState = messageState;
}
/**
* #return the networkErrorCode
*/
public String getNetworkErrorCode() {
return networkErrorCode;
}
/**
* #param networkErrorCode
* the networkErrorCode to set
*/
public void setNetworkErrorCode(String networkErrorCode) {
this.networkErrorCode = networkErrorCode;
}
/**
* #return the mesgFirstLines
*/
public String getMesgFirstLines() {
return mesgFirstLines;
}
/**
* #param mesgFirstLines
* the mesgFirstLines to set
*/
public void setMesgFirstLines(String mesgFirstLines) {
this.mesgFirstLines = mesgFirstLines;
}
/**
* #return the ip
*/
public String getIp() {
return ip;
}
/**
* #param ip
* the ip to set
*/
public void setIp(String ip) {
this.ip = ip;
}
/**
* #return the submitDate
*/
public DateTime getSubmitDate() {
return submitDate;
}
/**
* #param submitDate
* the submitDate to set
*/
public void setSubmitDate(DateTime submitDate) {
this.submitDate = submitDate;
}
/**
* #return the doneDate
*/
public DateTime getDoneDate() {
return doneDate;
}
/**
* #param doneDate
* the doneDate to set
*/
public void setDoneDate(DateTime doneDate) {
this.doneDate = doneDate;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
/**
* #return the srcTon
*/
public byte getSrcTon() {
return srcTon;
}
/**
* #param srcTon
* the srcTon to set
*/
public void setSrcTon(byte srcTon) {
this.srcTon = srcTon;
}
/**
* #return the srcNpi
*/
public byte getSrcNpi() {
return srcNpi;
}
/**
* #param srcNpi
* the srcNpi to set
*/
public void setSrcNpi(byte srcNpi) {
this.srcNpi = srcNpi;
}
/**
* #return the srcAddr
*/
public String getSrcAddr() {
return srcAddr;
}
/**
* #param srcAddr
* the srcAddr to set
*/
public void setSrcAddr(String srcAddr) {
this.srcAddr = srcAddr;
}
/**
* #return the destTon
*/
public byte getDestTon() {
return destTon;
}
/**
* #param destTon
* the destTon to set
*/
public void setDestTon(byte destTon) {
this.destTon = destTon;
}
/**
* #return the destNpi
*/
public byte getDestNpi() {
return destNpi;
}
/**
* #param destNpi
* the destNpi to set
*/
public void setDestNpi(byte destNpi) {
this.destNpi = destNpi;
}
/**
* #return the destAddr
*/
public String getDestAddr() {
return destAddr;
}
/**
* #param destAddr
* the destAddr to set
*/
public void setDestAddr(String destAddr) {
this.destAddr = destAddr;
}
/**
* #return the dlrState
*/
public char getDlrState() {
return dlrState;
}
/**
* #param dlrState
* the dlrState to set
*/
public void setDlrState(char dlrState) {
this.dlrState = dlrState;
}
}
Can someone tell me what can be the error? Thanks
To solve I have to download the source code and use it. I think there is a bug in the jar file I downloaded.
Download Project Source from
https://github.com/xetorthio/johm
Edit pom.xml
change Jedis version from 1.5.1 to 2.4.2 or latest
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.4.2</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
Compile project and build jar , use this new jar in your project

Resources