Related
Receiving an exception "BufferOverflowException" while running sikuli script via threads. The same script works properly without thread object. I have no clue what causes the bufferoverflowexception. Please guide.
Sample Code:-
import org.sikuli.script.*; // Library import
public class Sikuli {
private Screen screen = new Screen();
private Pattern getPattern(String imagePath) {
return new Pattern(imagePath);
}
public void click(String imagePath) throws FindFailed, InterruptedException {
screen.click(getPattern(imagePath));
}
public void sendKeys(String value) {
screen.type(value);
}
import Sukuli // Custom sikuli class import
public class foo {
Sikuli sk = new Sikuli();
public void test() {
Thread t1 = new Thread(() -> {
sk.click(new Pattern("imagePath"));
sk.type("fooboo");
});
t1.start();
}
}
From Sikuli Library Methods which are being referred by my class methods:-
public int type(String text) {
try {
return this.keyin((Object)null, text, 0);
} catch (FindFailed var3) {
return 0;
}
}
private <PFRML> int keyin(PFRML target, String text, int modifiers) throws FindFailed {
if (target != null && 0 == this.click(target, 0)) {
return 0;
} else {
Debug profiler = Debug.startTimer("Region.type", new Object[0]);
if (text != null && !"".equals(text)) {
String showText = "";
for(int i = 0; i < text.length(); ++i) {
showText = showText + Key.toJavaKeyCodeText(text.charAt(i));
}
String modText = "";
String modWindows = null;
if ((modifiers & 4) != 0) {
modifiers -= 4;
modifiers |= 4;
log(3, "Key.WIN as modifier", new Object[0]);
modWindows = "Windows";
}
if (modifiers != 0) {
modText = String.format("( %s ) ", KeyEvent.getKeyModifiersText(modifiers));
if (modWindows != null) {
modText = modText.replace("Meta", modWindows);
}
}
Debug.action("%s TYPE \"%s\"", new Object[]{modText, showText});
log(3, "%s TYPE \"%s\"", new Object[]{modText, showText});
profiler.lap("before getting Robot");
IRobot r = this.getRobotForRegion();
int pause = 20 + (Settings.TypeDelay > 1.0 ? 1000 : (int)(Settings.TypeDelay * 1000.0));
Settings.TypeDelay = 0.0;
profiler.lap("before typing");
r.typeStarts();
for(int i = 0; i < text.length(); ++i) {
r.pressModifiers(modifiers);
r.typeChar(text.charAt(i), KeyMode.PRESS_RELEASE);
r.releaseModifiers(modifiers);
r.delay(pause);
}
r.typeEnds();
profiler.lap("after typing, before waitForIdle");
r.waitForIdle();
profiler.end();
return 1;
} else {
return 0;
}
}
}
Trace logs:-
[log] CLICK on L[1517,53]#S(0) (555 msec)[log] TYPE "fooboo"Exception in thread "Thread-4" java.nio.BufferOverflowException
at java.nio.Buffer.nextPutIndex(Buffer.java:521)
at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:169)
at org.apache.maven.surefire.api.stream.AbstractStreamEncoder.encodeString(AbstractStreamEncoder.java:127)
at org.apache.maven.surefire.api.stream.AbstractStreamEncoder.encodeStringData(AbstractStreamEncoder.java:171)
at org.apache.maven.surefire.api.stream.AbstractStreamEncoder.encode(AbstractStreamEncoder.java:157)
at org.apache.maven.surefire.booter.spi.EventChannelEncoder.encodeMessage(EventChannelEncoder.java:398)
at org.apache.maven.surefire.booter.spi.EventChannelEncoder.setOutErr(EventChannelEncoder.java:188)
at org.apache.maven.surefire.booter.spi.EventChannelEncoder.testOutput(EventChannelEncoder.java:183)
at org.apache.maven.surefire.api.booter.ForkingRunListener.writeTestOutput(ForkingRunListener.java:113)
at org.apache.maven.surefire.api.booter.ForkingRunListener.writeTestOutput(ForkingRunListener.java:44)
at org.apache.maven.surefire.common.junit4.JUnit4RunListener.writeTestOutput(JUnit4RunListener.java:235)
at org.apache.maven.surefire.api.report.ConsoleOutputCapture$ForwardingPrintStream.println(ConsoleOutputCapture.java:144)
at org.sikuli.basics.Debug.log(Debug.java:881)
at org.sikuli.basics.Debug.action(Debug.java:645)
at org.sikuli.script.Region.keyin(Region.java:4613)
at org.sikuli.script.Region.type(Region.java:4493)
at Sikuli.sendKeys(Sikuli.java:87)
I've a problem with hibernate. I'm trying to save an object into a relational db with hibernate using orm.jar library generated by visual-paradigm tool. The problem is that it does not work but the program does not give me exceptions.
I tried to change my code but the program catches an exception and does not work.
MAIN:
CoordinatorIntrusione c = CoordinatorIntrusione.getInstance();
c.avviaRilevamento();
c.notifyProximityBySerraID(1, 4);
ArrayList<Integer> prova = new ArrayList<Integer>();
prova.add(2);
prova.add(1);
prova.add(9);
c.notifyImageBySerraID(1, prova);
System.out.println("ecco");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
c.ripristinaRilevamento(1, "1");
COORDINATORINTRUSIONE:
public class CoordinatorIntrusione {
private volatile static CoordinatorIntrusione coordinator = null;
private ThreadGroup groupBLThread;
public int avviaRilevamento() {
int code = 0;
EntitySmartFarm esm = EntitySmartFarm.getInstance();
EntityColtivazione[] colt = esm.getColtivazioniAttive();
if(colt.length==0) {
code=-1;
return code;
}
for(int i=0; i<colt.length; i++) {
EntitySerra serra = colt[i].getEntitySerra();
int id = serra.getId();
ControllerRilevaIntrusioneBL controller = new ControllerRilevaIntrusioneBL(id, groupBLThread, "worker"+i);
controller.start();
//System.out.println("ID :"+id);
}
return code;
}
public int negaID(int id, String matricola) {
//throw new UnsupportedOperationException();
int code = -1;
EntitySmartFarm esm = EntitySmartFarm.getInstance();
EntityColtivazione coltivazione = esm.getColtivazioneBySerraID(id);
if(coltivazione == null) return code;
String matResp = coltivazione.getEntitySerra().getResponsabile().getMatricola();
if (!matricola.equals(matResp)) return code;
ControllerRilevaIntrusioneBL controller = this.searchWorkerForID(id);
if (controller == null) return code;
code = controller.negaID();
return code;
}
public int ripristinaRilevamento(int id, String matricola) {
//throw new UnsupportedOperationException();
int code = -1;
EntitySmartFarm esm = EntitySmartFarm.getInstance();
EntityColtivazione coltivazione = esm.getColtivazioneBySerraID(id);
if(coltivazione == null) return code;
String matResp = coltivazione.getEntitySerra().getResponsabile().getMatricola();
if (!matricola.equals(matResp)) return code;
ControllerRilevaIntrusioneBL controller = this.searchWorkerForID(id);
if (controller == null) return code;
code = controller.ripristinaRilevamento();
return code;
}
public int confermaId(int id, String matricola) {
//throw new UnsupportedOperationException();
int code = -1;
EntitySmartFarm esm = EntitySmartFarm.getInstance();
EntityColtivazione coltivazione = esm.getColtivazioneBySerraID(id);
if(coltivazione == null) return code;
String matResp = coltivazione.getEntitySerra().getResponsabile().getMatricola();
if (!matricola.equals(matResp)) return code;
ControllerRilevaIntrusioneBL controller = this.searchWorkerForID(id);
if (controller == null) return code;
code = controller.confermaID();
return code;
// quindi se il code è negativo le matricole non combaciano, se positivo combaciano
}
protected ControllerRilevaIntrusioneBL searchWorkerForID(int idSerra) {
ControllerRilevaIntrusioneBL[] th = new ControllerRilevaIntrusioneBL[groupBLThread.activeCount()];
groupBLThread.enumerate(th);
int i=0;
while(i<th.length) {
if(th[i].getID() == idSerra) return th[i];
i++;
}
return null;
}
private CoordinatorIntrusione() {
groupBLThread = new ThreadGroup("workerCoordinator");
}
public void notifyProximityBySerraID(int idSerra, float value) {
ControllerRilevaIntrusioneBL thread = this.searchWorkerForID(idSerra);
thread.proximityValueArrived(value);
}
public void notifyImageBySerraID(int idSerra, ArrayList<Integer> img) {
ControllerRilevaIntrusioneBL thread = this.searchWorkerForID(idSerra);
thread.imgArrived(img);
}
public static CoordinatorIntrusione getInstance() {
if (coordinator == null) {
synchronized(CoordinatorIntrusione.class){ //Serve la sincronizzazione visto che è solo lettura
if(coordinator == null){
coordinator = new CoordinatorIntrusione();
}
}
}
return coordinator;
}
}
CONTROLLERRILEVAINTRUSIONEBL:
public class ControllerRilevaIntrusioneBL extends Thread{
private int id;
private float[] valoreProssimita;
private ArrayList<Integer> img;
private static final float criticalProxValue =5;
private Semaphore proxsem;
private Semaphore camsem;
private Semaphore ripristinasem;
private Semaphore waitsem ;
protected int rilevaVolti() {
//TODO with python script
//throw new UnsupportedOperationException();
return 0;
}
public synchronized int negaID() {
//throw new UnsupportedOperationException();
int code = 0;
if (waitsem.getQueueLength() > 0) {
waitsem.release();
code = 1;
}
else code = -1;
return code;
}
public synchronized int ripristinaRilevamento() {
//throw new UnsupportedOperationException();
int code = 0;
//System.out.println(ripristinasem.getQueueLength());
if (ripristinasem.getQueueLength() > 0) {
ripristinasem.release();
code = 1;
}
else code = -1;
//System.out.println(ripristinasem.getQueueLength());
return code;
}
public synchronized int confermaID() {
//throw new UnsupportedOperationException();
int code = 0;
if (waitsem.getQueueLength() > 0) {
waitsem.release();
code = 1;
}
else code = -1;
return code;
}
public int getID() {
return id;
}
public void setID(int id) {
this.id = id;
}
#Override
public void run() {
EntitySmartFarm esm = EntitySmartFarm.getInstance();
EntityColtivazione colt = esm.getColtivazioneBySerraID(id);
EntitySerra serra = colt.getEntitySerra();
EntitySensore proximity = serra.getSensoreProssimita();
EntitySensore camera = serra.getSensoreFotografico();
//ProxySerra proxyserra = ProxySerra.getInstance();
while (true) {
//MonitoraggioProssimità
//invio messaggio alla serra
try {
proxsem.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
proximity.setValore(valoreProssimita);
if(valoreProssimita[0] < criticalProxValue){
// invio messaggio camera alla serra
try {
camsem.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
float[] immagine = new float[img.size()];
int index = 0;
for (Integer value: img) {
immagine[index++] = value;
}
camera.setValore(immagine);
int ret = this.rilevaVolti();
if (ret == 0 || ret == -1) {
//New ProxyNotificationSystem
if (ret == 0) {
//ProxyNotificationSystem.inviosegnalazione();
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Europe/Rome"), Locale.ITALY);
Date today = calendar.getTime();
Date ora = calendar.getTime();
int[] array = img.stream().mapToInt(i -> i).toArray();
serra.addIntrusione(today, "Selvaggina", array, ora);
} else {
try {
waitsem.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
//proxynotsys.nviosegnalazione();
}
System.out.println("Thread: "+this.id+" bloccato");
try {
ripristinasem.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Thread: "+this.id+" Sbloccato");
}
}
}
}
public ControllerRilevaIntrusioneBL(int id, ThreadGroup group, String threadName){
super(group,threadName);
this.id = id;
valoreProssimita = new float[1];
img = new ArrayList<Integer>();
proxsem = new Semaphore(0);
camsem = new Semaphore(0);
ripristinasem = new Semaphore(0);
waitsem = new Semaphore(0);
}
public void proximityValueArrived(float value) {
valoreProssimita[0]=value;
proxsem.release();
}
public void imgArrived(ArrayList<Integer> img) {
this.img=img;
camsem.release();
}
}
ENTITYSERRA (first "addIntrusione" method catches exception and does not work, second "addIntrusione" method does not catch but does not work anyway):
public class EntitySerra {
public EntitySerra() {
}
private java.util.Set this_getSet (int key) {
if (key == vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_ENTITYSERRA_ENTITYEMPLOYERS) {
return ORM_entityEmployers;
}
else if (key == vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_ENTITYSERRA_ENTITYSENSORES) {
return ORM_entitySensores;
}
else if (key == vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_ENTITYSERRA_ENTITYINTRUSIONES) {
return ORM_entityIntrusiones;
}
else if (key == vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_ENTITYSERRA_ENTITYLETTURAS) {
return ORM_entityLetturas;
}
return null;
}
org.orm.util.ORMAdapter _ormAdapter = new org.orm.util.AbstractORMAdapter() {
public java.util.Set getSet(int key) {
return this_getSet(key);
}
};
private int id;
private java.util.Set ORM_entityEmployers = new java.util.HashSet();
private java.util.Set ORM_entitySensores = new java.util.HashSet();
private java.util.Set ORM_entityIntrusiones = new java.util.HashSet();
private java.util.Set ORM_entityLetturas = new java.util.HashSet();
private void setId(int value) {
this.id = value;
}
public int getId() {
return id;
}
public int getORMID() {
return getId();
}
public void setORM_EntityEmployers(java.util.Set value) {
this.ORM_entityEmployers = value;
}
public java.util.Set getORM_EntityEmployers() {
return ORM_entityEmployers;
}
public final vista_architetturale_gestoresmartfarm.entity2.EntityEmployerSetCollection entityEmployers = new vista_architetturale_gestoresmartfarm.entity2.EntityEmployerSetCollection(this, _ormAdapter, vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_ENTITYSERRA_ENTITYEMPLOYERS, vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_MUL_ONE_TO_MANY);
public void setORM_EntitySensores(java.util.Set value) {
this.ORM_entitySensores = value;
}
public java.util.Set getORM_EntitySensores() {
return ORM_entitySensores;
}
public final vista_architetturale_gestoresmartfarm.entity2.EntitySensoreSetCollection entitySensores = new vista_architetturale_gestoresmartfarm.entity2.EntitySensoreSetCollection(this, _ormAdapter, vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_ENTITYSERRA_ENTITYSENSORES, vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_MUL_ONE_TO_MANY);
public void setORM_EntityIntrusiones(java.util.Set value) {
this.ORM_entityIntrusiones = value;
}
public java.util.Set getORM_EntityIntrusiones() {
return ORM_entityIntrusiones;
}
public final vista_architetturale_gestoresmartfarm.entity2.EntityIntrusioneSetCollection entityIntrusiones = new vista_architetturale_gestoresmartfarm.entity2.EntityIntrusioneSetCollection(this, _ormAdapter, vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_ENTITYSERRA_ENTITYINTRUSIONES, vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_MUL_ONE_TO_MANY);
public void setORM_EntityLetturas(java.util.Set value) {
this.ORM_entityLetturas = value;
}
public java.util.Set getORM_EntityLetturas() {
return ORM_entityLetturas;
}
public final vista_architetturale_gestoresmartfarm.entity2.EntityLetturaSetCollection entityLetturas = new vista_architetturale_gestoresmartfarm.entity2.EntityLetturaSetCollection(this, _ormAdapter, vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_ENTITYSERRA_ENTITYLETTURAS, vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_MUL_ONE_TO_MANY);
public String getNotifyInformationResponsabile() {
//TODO: Implement Method
String recapito = null;
Iterator<EntityEmployer> it = ORM_entityEmployers.iterator();
boolean trovato = false;
while(trovato == false && it.hasNext()){
EntityEmployer empTemp = it.next();
if(empTemp.getTipo().equals("responsabile")){
trovato = true;
recapito = empTemp.getRecapito();
}
}
return recapito;
}
public void salvaLettura() {
//TODO: Implement Method
throw new UnsupportedOperationException();
}
public void salvaLettura2() {
//TODO: Implement Method
throw new UnsupportedOperationException();
}
public void addIntrusione(java.util.Date data, String tipo, int[] img, java.util.Date ora) {
//TODO: Implement Method
EntityIntrusione intrusione = new EntityIntrusione (data, ora, tipo, img);
//DA TESTARE IMPORTANTISSIMO
ORM_entityIntrusiones.add(intrusione);
try {
//EntitySerraDAO.save(this);
EntityIntrusioneDAO.save(intrusione);
} catch (PersistentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*public synchronized void addIntrusione(java.util.Date data, String tipo, int[] img, java.util.Date ora){
//TODO: Implement Method
EntityIntrusione intrusione = new EntityIntrusione (data,ora,tipo,img);
//DA TESTARE IMPORTANTISSIMO
this.ORM_entityIntrusiones.add(intrusione);
this.entityIntrusiones.add(intrusione);
try {
Stream<EntityIntrusione> stream = this.ORM_entityIntrusiones.stream();
// salva l'ultimo elem
EntityIntrusioneDAO.save(stream.reduce((a, b) -> b).orElse(null));
} catch (PersistentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}*/
public EntitySerra(vista_architetturale_gestoresmartfarm.entity2.EntitySerraDAO serra) {
//TODO: Implement Method
throw new UnsupportedOperationException();
}
public String[] getNotifyInformationEmployers() {
//TODO: Implement Method
throw new UnsupportedOperationException();
}
public vista_architetturale_gestoresmartfarm.entity2.EntitySensore getSensoreProssimita() {
EntitySensore sensProssimita = null;
Iterator<EntitySensore> it = ORM_entitySensores.iterator();
boolean trovato = false;
while(trovato == false && it.hasNext()){
EntitySensore sensTemp = it.next();
if(sensTemp.getTipo().equals("prossimita")){
trovato = true;
sensProssimita = sensTemp;
}
}
return sensProssimita;
}
public vista_architetturale_gestoresmartfarm.entity2.EntitySensore getSensoreFotografico() {
EntitySensore sensFotocamera = null;
Iterator<EntitySensore> it = ORM_entitySensores.iterator();
boolean trovato = false;
while(trovato == false && it.hasNext()){
EntitySensore sensTemp = it.next();
if(sensTemp.getTipo().equals("cam")){
trovato = true;
sensFotocamera = sensTemp;
}
}
return sensFotocamera;
}
public vista_architetturale_gestoresmartfarm.entity2.EntityEmployer getResponsabile() {
//TODO: Implement Method
EntityEmployer responsabile = null;
Iterator<EntityEmployer> it = ORM_entityEmployers.iterator();
boolean trovato = false;
while(trovato == false && it.hasNext()){
EntityEmployer empTemp = it.next();
if(empTemp.getTipo().equals("responsabile")){
trovato = true;
responsabile = empTemp;
}
}
return responsabile;
}
public String toString() {
return String.valueOf(getId());
}
}
ENTITYINTRUSIONEDAO:
public class EntityIntrusioneDAO {
public static boolean save(vista_architetturale_gestoresmartfarm.entity2.EntityIntrusione entityIntrusione) throws PersistentException {
try {
vista_architetturale_gestoresmartfarm.entity2.ProgettoPSSSAgosVersionPersistentManager.instance().saveObject(entityIntrusione);
return true;
}
catch (Exception e) {
e.printStackTrace();
throw new PersistentException(e);
}
}
}
PERSISTENT MANAGER:
public class ProgettoPSSSAgosVersionPersistentManager extends PersistentManager {
private static PersistentManager _instance = null;
private static SessionType _sessionType = SessionType.THREAD_BASE;
private static int _timeToAlive = 60000;
private static JDBCConnectionSetting _connectionSetting = null;
private static Properties _extraProperties = null;
private static String _configurationFile = null;
private ProgettoPSSSAgosVersionPersistentManager() throws PersistentException {
super(_connectionSetting, _sessionType, _timeToAlive, new String[] {}, _extraProperties, _configurationFile);
setFlushMode(FlushMode.AUTO);
}
public String getProjectName() {
return PROJECT_NAME;
}
public static synchronized final PersistentManager instance() throws PersistentException {
if (_instance == null) {
_instance = new ProgettoPSSSAgosVersionPersistentManager();
}
return _instance;
}
public void disposePersistentManager() throws PersistentException {
_instance = null;
super.disposePersistentManager();
}
public static void setSessionType(SessionType sessionType) throws PersistentException {
if (_instance != null) {
throw new PersistentException("Cannot set session type after create PersistentManager instance");
}
else {
_sessionType = sessionType;
}
}
public static void setAppBaseSessionTimeToAlive(int timeInMs) throws PersistentException {
if (_instance != null) {
throw new PersistentException("Cannot set session time to alive after create PersistentManager instance");
}
else {
_timeToAlive = timeInMs;
}
}
public static void setJDBCConnectionSetting(JDBCConnectionSetting aConnectionSetting) throws PersistentException {
if (_instance != null) {
throw new PersistentException("Cannot set connection setting after create PersistentManager instance");
}
else {
_connectionSetting = aConnectionSetting;
}
}
public static void setHibernateProperties(Properties aProperties) throws PersistentException {
if (_instance != null) {
throw new PersistentException("Cannot set hibernate properties after create PersistentManager instance");
}
else {
_extraProperties = aProperties;
}
}
public static void setConfigurationFile(String aConfigurationFile) throws PersistentException {
if (_instance != null) {
throw new PersistentException("Cannot set configuration file after create PersistentManager instance");
}
else {
_configurationFile = aConfigurationFile;
}
}
public static void saveJDBCConnectionSetting() {
PersistentManager.saveJDBCConnectionSetting(PROJECT_NAME, _connectionSetting);
}
}
The exception caught is:
org.orm.PersistentException: org.hibernate.PropertyValueException: not-null property references a null or transient value : vista_architetturale_gestoresmartfarm.entity2.EntityIntrusione._vista_architetturale_gestoresmartfarm.entity2.EntitySerra.ORM_EntityIntrusionesBackref
at org.orm.PersistentSession.saveOrUpdate(PersistentSession.java:598)
at org.orm.PersistentManager.saveObject(PersistentManager.java:326)
at vista_architetturale_gestoresmartfarm.entity2.EntityIntrusioneDAO.save(EntityIntrusioneDAO.java:304)
at vista_architetturale_gestoresmartfarm.entity2.EntitySerra.addIntrusione(EntitySerra.java:146)
at vista_architetturale_gestoresmartfarm.business_logic.ControllerRilevaIntrusioneBL.run(ControllerRilevaIntrusioneBL.java:139)
Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value : vista_architetturale_gestoresmartfarm.entity2.EntityIntrusione._vista_architetturale_gestoresmartfarm.entity2.EntitySerra.ORM_EntityIntrusionesBackref
at org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:89)
at org.hibernate.action.internal.AbstractEntityInsertAction.nullifyTransientReferencesIfNotAlready(AbstractEntityInsertAction.java:115)
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:69)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:625)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:279)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:260)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:305)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:318)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:275)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:97)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:655)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:647)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:642)
at org.orm.PersistentSession.saveOrUpdate(PersistentSession.java:596)
... 4 more
org.orm.PersistentException: org.orm.PersistentException: org.hibernate.PropertyValueException: not-null property references a null or transient value : vista_architetturale_gestoresmartfarm.entity2.EntityIntrusione._vista_architetturale_gestoresmartfarm.entity2.EntitySerra.ORM_EntityIntrusionesBackref
at vista_architetturale_gestoresmartfarm.entity2.EntityIntrusioneDAO.save(EntityIntrusioneDAO.java:309)
at vista_architetturale_gestoresmartfarm.entity2.EntitySerra.addIntrusione(EntitySerra.java:146)
at vista_architetturale_gestoresmartfarm.business_logic.ControllerRilevaIntrusioneBL.run(ControllerRilevaIntrusioneBL.java:139)
Caused by: org.orm.PersistentException: org.hibernate.PropertyValueException: not-null property references a null or transient value : vista_architetturale_gestoresmartfarm.entity2.EntityIntrusione._vista_architetturale_gestoresmartfarm.entity2.EntitySerra.ORM_EntityIntrusionesBackref
at org.orm.PersistentSession.saveOrUpdate(PersistentSession.java:598)
at org.orm.PersistentManager.saveObject(PersistentManager.java:326)
at vista_architetturale_gestoresmartfarm.entity2.EntityIntrusioneDAO.save(EntityIntrusioneDAO.java:304)
... 2 more
Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value : vista_architetturale_gestoresmartfarm.entity2.EntityIntrusione._vista_architetturale_gestoresmartfarm.entity2.EntitySerra.ORM_EntityIntrusionesBackref
at org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:89)
at org.hibernate.action.internal.AbstractEntityInsertAction.nullifyTransientReferencesIfNotAlready(AbstractEntityInsertAction.java:115)
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:69)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:625)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:279)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:260)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:305)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:318)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:275)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:97)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:655)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:647)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:642)
at org.orm.PersistentSession.saveOrUpdate(PersistentSession.java:596)
... 4 more
You can specify the Error Handling method when generating ORM code. May I know which option you selected?
We are running hazelcast 2.5 as a cluster to replicate objects through applications. There are, at the moment, one producer and 3 consumers. The updates from the writer go as high as 10000 per minute and the consumers read every second searching for updates in the clustered map.The writer is a java native application running under a Debian 8 server with java 7. The hazelcast server is on the same machine as the producer but on an independent application. All the consumers are tomcat 7 apps running under a Debian 8 machine with java 7. The problem we are facing is that in average about 4 percent of the data clustered is reaching the consumer´s end garbled in the shared map. The code for the producer is the following :
Long imei;
Integer clase;
HazelCastobjGpsData datoGps;
HazelCastobjTelemetria datoTelemetria;
Set<HazelCastpkQueue> keys = HazelCast.tmpQueue.keySet();
for (Iterator<HazelCastpkQueue> i = keys.iterator(); i.hasNext();) {
HazelCastpkQueue current = i.next();
clase = current.getClase();
imei = current.getImei();
if (clase == CLASE_GPS) // GPS
{
try {
HazelCast.clienteHC.getLock(imei).lock();
datoGps = (HazelCastobjGpsData) HazelCast.tmpQueue
.remove(current);
HazelCast.instMapGPS.put(current.getImei(), datoGps);
HazelCast.instQueue.put(new HazelCastpkQueue(imei,
CLASE_GPS), CLASE_GPS);
} catch (Throwable t) {
System.out.println("Error HazelCast Gps Update: " + imei
+ " :" + t.getMessage());
if (!HazelCast.clienteHC.isActive()) {
System.out.println("Hazelcast no activo");
}
} finally {
HazelCast.clienteHC.getLock(imei).unlock();
}
} else // Telemetria
{
try {
HazelCast.clienteHC.getLock(imei).lock();
datoTelemetria = (HazelCastobjTelemetria) HazelCast.tmpQueue
.remove(current);
HazelCast.instMapTelemetria.put(new HazelCastpkQueue(imei,
clase), datoTelemetria);
HazelCast.instQueue.put(new HazelCastpkQueue(imei, clase),
clase);
} catch (Throwable t) {
System.out.println("Error HazelCast Telemetria Update: "
+ imei + " :" + t.getMessage());
if (!HazelCast.clienteHC.isActive()) {
System.out.println("Hazelcast no activo");
}
} finally {
HazelCast.clienteHC.getLock(imei).unlock();
}
}
}
Where HazelCastobjGpsData datoGps; is the object to be rescued by the consumers and HazelCast.instMapGPS.put(current.getImei(), datoGps); is the map with problems. It has a long as a key.
The code for the server is the following:
public class HazelServer {
#SuppressWarnings("unused")
private static ConcurrentMap<Long,HazelCastobjGpsData> instMapGPS;
#SuppressWarnings("unused")
private static ConcurrentMap<HazelCastpkQueue,HazelCastobjTelemetria> instMapTelemetria;
#SuppressWarnings("unused")
private static ConcurrentMap<HazelCastpkQueue,Integer> instQueue;
#SuppressWarnings("unused")
private static BlockingQueue<HazelCastpkTisPanicoQueue> tisPanicQueue;
public static void main(final String[] args) {
System.out.println("HazelCast Server init 03/03/2015");
init();
System.out.println("OK");
}
private static void init() {
try {
HazelcastInstance hcServer = Hazelcast.newHazelcastInstance(null);
instMapGPS = hcServer.getMap("gps");
instMapTelemetria = hcServer.getMap("telemetria");
instQueue = hcServer.getMap("colagpstele");
tisPanicQueue = hcServer.getQueue("cola_panico_tis");
} catch (Throwable t) {
System.out.println("Error al tratar de obtener mapas: " + t.getMessage());
}
}
}
The consumers code is the following
public static void fetchHazelCast() {
try {
if (GetHazelCast.isHazelcastActive()) {
double errores = 0;
double count=0;
Set<HazelCastpkQueue> keys = GetHazelCast.hcQueue.keySet();
for (final Iterator<HazelCastpkQueue> i = keys.iterator(); i.hasNext();) {
HazelCastpkQueue currentKey = i.next();
if (currentKey.getClase() == CLASE_GPS) // GPS Base
{
if(Realtime.newGPS(GetHazelCast.hcGPS.get(currentKey.getImei()))){
errores++;
}
count++;
} else // Telemetria
{
Realtime.newTelemetria(GetHazelCast.hcTelemetria.get(currentKey));
}
//count++;
GetHazelCast.hcQueue.remove(currentKey);
currentKey = null;
}
/*ReqInit.logger.warn("Errores "+(double)errores);
ReqInit.logger.warn("Cantidad "+(double)count);
ReqInit.logger.warn("Porcentaje "+(double) ((((double)errores)*100.0f)/(double)count));*/
if(count>0){
double promedio = (double) ((((double)errores)*100.0f)/(double)count);
CloudWatchSubmit.sendMetric("metricasreq", "errores", errores);
CloudWatchSubmit.sendMetric("metricasreq", "cantidad", count);
CloudWatchSubmit.sendMetric("metricasreq", "erroresporcentaje", promedio);
}
keys = null;
} else {
System.out.println("Hazelcast no activo...");
GetHazelCast.contectarHZRealTime();
}
} catch (Exception e) {
e.printStackTrace();
}
}
note that the consumer only takes out the data that has been updated recently, this is done because there is a map whith keys that are been updated, once the data is out thar key is removed from that map.
The following is the code of the object
public class HazelCastobjGpsData implements DataSerializable {
private static final long serialVersionUID = 1L;
private Calendar utc;
private Calendar lastupdate;
private String now = "n/a";
private double latitud = 0.0, longitud = 0.0, altitud = 0.0,
velocidad = 0.0, cog = 0.0, nsat = 4.0, hdop = 2.0, adc1 = -200,
adc2 = -200, adc3 = -200, adc4 = -200, bateria = -1;
private int ignicion, io1 = -1, io2 = -1, io3 = -1, io4 = -1, power = -1,
antirobo = -1, panico = -1;
private long imei = 0L, driverId = -1;
private boolean valid = true;
private long odometro = -1L;
private long horometro = -1L;
private String ip = "N/A";
private long ibutton2 = -1;
private long ibutton3 = -1;
private long ibutton4 = -1;
private long odometroInterno = -1L;
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
private double anterior_lat = 0.0;
private double anterior_lon = 0.0;
private double anterior_sog = 0;
private double anterior_cog = 0;
private double anterior_ignicion = 0;
private long anterior_odometro = 0;
private long anterior_horometro = 0;
private long delta_time = 0;
private double delta_dist = 0;
private long trailerId = -1L;
private long tripTime = 0L;
private long horometroInterno = 0L;
public long getHorometroInterno() {
return horometroInterno;
}
public void setHorometroInterno(long horometroInterno) {
this.horometroInterno = horometroInterno;
}
public void setAnterior(HazelCastobjGpsData anterior) {
this.setDelta_dist(Math.round((new Geo(this.latitud, this.longitud)
.distanceKM(new Geo(anterior.getLatitud(), anterior
.getLongitud()))) * 1000));
this.setDelta_time((this.getUTC().getTimeInMillis() - anterior.getUTC()
.getTimeInMillis()) / 1000);
this.setAnterior_cog(anterior.getCOG());
this.setAnterior_sog(anterior.getVelocidad());
this.setAnterior_lat(anterior.getLatitud());
this.setAnterior_lon(anterior.getLongitud());
this.setAnterior_ignicion(anterior.getIgnicion());
}
private boolean fromDB = false;
private int evento = 0; // Por tiempo, curva u otro
public Calendar getUTC() {
return utc;
}
public String getNow() {
return now;
}
public double getLatitud() {
return latitud;
}
public double getLongitud() {
return longitud;
}
public double getAltitud() {
return altitud;
}
public double getVelocidad() {
return velocidad;
}
public double getCOG() {
return cog;
}
public String getCOGtoString() {
String txtDireccion = "";
if ((this.cog >= 0) && (this.cog <= 5)) {
txtDireccion = "Norte";
} else if ((this.cog > 5) && (this.cog <= 85)) {
txtDireccion = "Noreste (NorOriente)";
}
else if ((this.cog > 85) && (this.cog <= 95)) {
txtDireccion = "Este (Oriente)";
} else if ((this.cog > 95) && (this.cog <= 175)) {
txtDireccion = "Sureste (SurOriente)";
}
else if ((this.cog > 175) && (this.cog <= 185)) {
txtDireccion = "Sur";
}
else if ((this.cog > 185) && (this.cog <= 265)) {
txtDireccion = "Suroeste (SurPoniente)";
} else if ((this.cog > 265) && (this.cog <= 275)) {
txtDireccion = "Oeste (Poniente)";
} else if ((this.cog > 275) && (this.cog <= 355)) {
txtDireccion = "Noroeste (NorPoniente)";
}
else if ((this.cog > 355) && (this.cog <= 360)) {
txtDireccion = "Norte";
}
return txtDireccion;
}
public double getNsat() {
return nsat;
}
public double getHdop() {
return hdop;
}
public double getAdc1() {
return adc1;
}
public double getAdc2() {
return adc2;
}
public double getBateria() {
return bateria;
}
public int getIgnicion() {
return ignicion;
}
public int getIo(int index) {
int io_array[] = { 0, this.io1, this.io2, this.io3, this.io4,this.panico };
return io_array[index];
}
public int getIo1() {
return io1;
}
public int getIo2() {
return io2;
}
public int getIo3() {
return io3;
}
public int getIo4() {
return io4;
}
public int getPower() {
return power;
}
public long getHorometro() {
return horometro;
}
public long getOdometro() {
return odometro;
}
public int getEvento() {
return evento;
}
public int getAntirobo() {
return antirobo;
}
public int getPanico() {
return panico;
}
public long getImei() {
return imei;
}
public long getDriverId() {
return driverId;
}
public boolean isValid() {
return valid;
}
public Calendar getLastupdate() {
return lastupdate;
}
public void setLastupdate(Calendar lastupdate) {
this.lastupdate = lastupdate;
}
public HazelCastobjGpsData() {
}
public HazelCastobjGpsData(final GpsData original) {
this.imei = original.getImei();
this.driverId = original.getDriverId();
this.panico = original.getPanico();
this.antirobo = original.getAntirobo();
this.ignicion = original.getIgnicion();
this.now = original.getNow();
this.ip = original.getIpaddress();
if (original.getDriverIdArray() != null
&& original.getDriverIdArray().length == 4) {
this.ibutton2 = original.getDriverIdArray()[1];
this.ibutton3 = original.getDriverIdArray()[2];
this.ibutton4 = original.getDriverIdArray()[3];
} else {
this.ibutton2 = -1;
this.ibutton3 = -1;
this.ibutton4 = -1;
}
if (original.getTimeCalendar() == null || !original.isFullProcessed()
|| original.isOnlyStatus()) {
this.valid = false;
Calendar fecha_gps = Calendar.getInstance(TimeZone
.getTimeZone("UTC"));
fecha_gps.setTimeInMillis(0);
this.utc = fecha_gps;
this.lastupdate = original.getLastUpdate();
} else {
this.utc = original.getTimeCalendar();
this.latitud = original.getLatitud();
this.longitud = original.getLongitud();
this.altitud = original.getAltitud();
this.velocidad = original.getVelocidad();
this.cog = original.getCOG();
this.nsat = original.getNSAT();
this.io1 = original.getIo1();
this.io2 = original.getIo2();
this.io3 = original.getIo3();
this.io4 = original.getIo4();
this.hdop = original.getHdop();
this.adc1 = original.getAdc();
this.adc2 = original.getAdc2();
this.power = original.getPower();
this.bateria = original.getBateria();
this.odometro = original.getOdometro();
this.horometro = original.getHorometro();
this.evento = original.getEvento();
this.setTrailerId(original.getTrailerId());
this.setTripTime(original.getTripTime());
this.setHorometroInterno(original.getHorometroInterno());
}
}
// Para INIT por BD
public HazelCastobjGpsData(final boolean fromDB, final long imei,
final String registro, final Calendar utc,
final Calendar lastupdate, final long driverid,
final double latitud, final double longitud, final double altitud,
final double velocidad, final double cog, final double nsat,
final double hdop, final double adc1, final double adc2,
final double adc3, final double adc4, final double bateria,
final int ignicion, final int io1, final int io2, final int io3,
final int io4, final int power, final int antirobo,
final int panico, final long odometro, final long horometro,
final int evento) {
this.imei = imei;
this.driverId = driverid;
this.panico = panico;
this.antirobo = antirobo;
this.ignicion = ignicion;
this.now = registro;
this.utc = utc;
this.lastupdate = lastupdate;
this.latitud = latitud;
this.longitud = longitud;
this.altitud = altitud;
this.velocidad = velocidad;
this.cog = cog;
this.nsat = nsat;
this.io1 = io1;
this.io2 = io2;
this.io3 = io3;
this.io4 = io4;
this.hdop = hdop;
this.adc1 = adc1;
this.adc2 = adc2;
this.adc3 = adc3;
this.adc4 = adc4;
this.power = power;
this.bateria = bateria;
this.horometro = horometro;
this.odometro = odometro;
this.setFromDB(fromDB);
}
#Override
public void readData(final DataInput arg0) throws IOException {
this.utc = Calendar.getInstance();
try {
this.utc.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
.parse(arg0.readUTF()));
} catch (ParseException e) {
ReqInit.logger.fatal(e.getMessage(), e);
}
this.lastupdate = Calendar.getInstance();
try {
this.lastupdate.setTime(new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss.SSS").parse(arg0.readUTF()));
} catch (ParseException e) {
ReqInit.logger.fatal(e.getMessage(), e);
}
this.now = arg0.readUTF();
this.latitud = arg0.readDouble();
this.longitud = arg0.readDouble();
this.altitud = arg0.readDouble();
this.velocidad = arg0.readDouble();
this.cog = arg0.readDouble();
this.nsat = arg0.readDouble();
this.hdop = arg0.readDouble();
this.adc1 = arg0.readDouble();
this.adc2 = arg0.readDouble();
this.adc3 = arg0.readDouble();
this.adc4 = arg0.readDouble();
this.bateria = arg0.readDouble();
this.ignicion = arg0.readInt();
this.io1 = arg0.readInt();
this.io2 = arg0.readInt();
this.io3 = arg0.readInt();
this.io4 = arg0.readInt();
this.power = arg0.readInt();
this.antirobo = arg0.readInt();
this.panico = arg0.readInt();
this.imei = arg0.readLong();
this.driverId = arg0.readLong();
this.valid = arg0.readBoolean();
this.odometro = arg0.readLong();
this.horometro = arg0.readLong();
this.evento = arg0.readInt();
this.ip = arg0.readUTF();
this.trailerId = arg0.readLong();
this.tripTime = arg0.readLong();
this.horometroInterno = arg0.readLong();
this.ibutton2 = arg0.readLong();
this.ibutton3 = arg0.readLong();
this.ibutton4 = arg0.readLong();
this.odometroInterno = arg0.readLong();
}
#Override
public void writeData(final DataOutput arg0) throws IOException {
arg0.writeUTF(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
.format(utc.getTime()));
arg0.writeUTF(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
.format(lastupdate.getTime()));
arg0.writeUTF(now);
arg0.writeDouble(latitud);
arg0.writeDouble(longitud);
arg0.writeDouble(altitud);
arg0.writeDouble(velocidad);
arg0.writeDouble(cog);
arg0.writeDouble(nsat);
arg0.writeDouble(hdop);
arg0.writeDouble(adc1);
arg0.writeDouble(adc2);
arg0.writeDouble(adc3);
arg0.writeDouble(adc4);
arg0.writeDouble(bateria);
arg0.writeInt(ignicion);
arg0.writeInt(io1);
arg0.writeInt(io2);
arg0.writeInt(io3);
arg0.writeInt(io4);
arg0.writeInt(power);
arg0.writeInt(antirobo);
arg0.writeInt(panico);
arg0.writeLong(imei);
arg0.writeLong(driverId);
arg0.writeBoolean(valid);
arg0.writeLong(odometro);
arg0.writeLong(horometro);
arg0.writeInt(evento);
arg0.writeUTF(ip);
arg0.writeLong(trailerId);
arg0.writeLong(tripTime);
arg0.writeLong(horometroInterno);
arg0.writeLong(ibutton2);
arg0.writeLong(ibutton3);
arg0.writeLong(ibutton4);
arg0.writeLong(odometroInterno);
}
public boolean isFromDB() {
return fromDB;
}
public void setFromDB(boolean fromDB) {
this.fromDB = fromDB;
}
public long getDeltaTime() {
return delta_time;
}
private void setDelta_time(long delta_time) {
this.delta_time = delta_time;
}
public double getAnteriorSog() {
return anterior_sog;
}
private void setAnterior_sog(double anterior_sog) {
this.anterior_sog = anterior_sog;
}
public double getAnterior_lon() {
return anterior_lon;
}
private void setAnterior_lon(double anterior_lon) {
this.anterior_lon = anterior_lon;
}
public double getAnterior_lat() {
return anterior_lat;
}
private void setAnterior_lat(double anterior_lat) {
this.anterior_lat = anterior_lat;
}
public double getAnteriorCog() {
return anterior_cog;
}
private void setAnterior_cog(double anterior_cog) {
this.anterior_cog = anterior_cog;
}
public double getAnteriorIgnicion() {
return anterior_ignicion;
}
private void setAnterior_ignicion(double anterior_ignicion) {
this.anterior_ignicion = anterior_ignicion;
}
public double getDeltaDist() {
return delta_dist;
}
private void setDelta_dist(double delta_dist) {
this.delta_dist = delta_dist;
}
public long getAnterior_odometro() {
return anterior_odometro;
}
public long getAnterior_horometro() {
return anterior_horometro;
}
public double getAdc3() {
return adc3;
}
public void setAdc3(double adc3) {
this.adc3 = adc3;
}
public double getAdc4() {
return adc4;
}
public void setAdc4(double adc4) {
this.adc4 = adc4;
}
public long getTrailerId() {
return trailerId;
}
public void setTrailerId(long trailerId) {
this.trailerId = trailerId;
}
public long getTripTime() {
return tripTime;
}
public void setTripTime(long tripTime) {
this.tripTime = tripTime;
}
public long getIbutton2() {
return ibutton2;
}
public void setIbutton2(long ibutton2) {
this.ibutton2 = ibutton2;
}
public long getIbutton3() {
return ibutton3;
}
public void setIbutton3(long ibutton3) {
this.ibutton3 = ibutton3;
}
public long getIbutton4() {
return ibutton4;
}
public void setIbutton4(long ibutton4) {
this.ibutton4 = ibutton4;
}
public long getOdometroInterno() {
return odometroInterno;
}
public void setOdometroInterno(long odometroInterno) {
this.odometroInterno = odometroInterno;
}
}
We are aware that we are using and older version of hazelcast but upgrade it is not an option yet, we want to know if there is a code issue first. Could you please help me to find the issue ?
I am trying to implement paging in an already running application, it works like mongodb where you get a query with bunch of parameters like
searchConditions ,limit( how many docs you want), skip ( skip these many docs)
and so on
and the response is back in json my task is to generate the previous and next link to the query that means previous page and the next page as per query
I came up with a method below
public Paging generateLink(RequestFilter filter) {
int prev_skip;
int prev_limit;
String pagePrev = "";
String pageNext = "";
int next_skip;
int next_limit;
String searchCondition = JsonUtils.toSimpleJsonString(filter.getSearch());
String url = "http://isgswmdi1n1.nam.nsroot.net:7014/account-search/rest/api/v1/pmm";
//properties.getProperty("paging.link");
System.out.println(url);
Paging pagingOption = new Paging();
Result result = new Result();
int count = luceneSearchService.searchCount(filter);
try {
if (count > 1) {
if (filter.getSkip() > 0) {
prev_skip = Math.max((filter.getSkip() - 1), 0);
prev_limit = filter.getLimit();
pagePrev = url + "?search=" + searchCondition + "&skip=" + prev_skip + "$limit=" + prev_limit;
} else{
result.setPaging(null);
return null;
}
if (count > (filter.getLimit() + filter.getSkip())) {
next_skip = (filter.getSkip() + filter.getLimit());
next_limit = filter.getLimit();
pageNext = url + "?search=" + searchCondition + "&skip=" + next_skip + "$limit=" + next_limit;
} else{
result.setPaging(null);
return null;
}
pagingOption.setPagePrev(pagePrev);
pagingOption.setPageNext(pageNext);
result.setPaging(pagingOption);
}
return pagingOption;
} catch (NullPointerException n)
{
n.printStackTrace();
return pagingOption;
}
}
call to generateLink method
return Result.ok(resultRow, generateLink(filter));
the ok response method in the Result class
public static Result ok(List<ResultRow> resultRows, Paging paging) {
if (paging != null) {
return new Result(resultRows, 200, "Completed", paging);
} else
return new Result(resultRows, 200, "Completed");
}
Underlying paging class
public class Paging implements Serializable {
public String getPagePrev() {
return pagePrev;
}
public void setPagePrev(String pagePrev) {
this.pagePrev = pagePrev;
}
#JsonProperty("pagePrev")
private String pagePrev;
public String getPageNext() {
return pageNext;
}
public void setPageNext(String pageNext) {
this.pageNext = pageNext;
}
#JsonProperty("pageNext")
private String pageNext;
}
but my test method is failing
#Test
public void search_allFilterParamsAreDefined_hp() throws Exception {
// given
Map<String, Serializable> searchConditions = singletonMap("shortName", "GO");
List<String> returnFields = asList("shortname", "gfcid");
String returnFieldsStr = returnFields.stream().collect(joining(","));
RequestFilter filter = RequestFilter.create(searchConditions, returnFieldsStr, 5, 10, true);
int resultSize = 20;
List<ResultRow> searchResult = getSearchResult(resultSize);
when(luceneSearchService.search(filter)).thenReturn(searchResult);
when(luceneSearchService.searchCount(filter)).thenReturn(resultSize);
// do
Result result = searchCoordinator.search(filter);
// verify
assertEquals(searchResult, result.getRows());
assertReturnFields(returnFields, result.getRows());
assertNotNull(result.getPaging());
Map<String, String> nextParams = getQueryParams(result.getPaging().getPageNext());
assertParam(nextParams, "search", toSimpleJsonString(searchConditions));
assertParam(nextParams, "skip", "15");
assertParam(nextParams, "limit", "10");
}
I'm doing a simple MessageRenderer.
It's specification:
Render message based on an Context (it's a map that's contains all key/value pair parameters)
Supports simple render such as: Your username is << username >>. Assume username in the context is barcelona and the result will be Your username is Barcelona.
Supported function-like object. Example: Current time is << now() >>, now(): is an object that will returns a string of current date time. And result will be: Current time is 2011-05-30
Each parameter of function can also be templated: Current time is << now( << date_format >> ) >> . This template returns a string of current date time with format is the value of key 'date_format' retrieved from the Context. Assume date_format in Context is dd/MM/yyyy and the result will be: Current time is 30/05/2011
Each parameter of function can also be templated with a different method call: Time is << now_locale ( << getLocale() >> ). Assume that getLocale() is an function object that will be return a locale is en_US and the result will be: Time is 2011/05/30 11:20:34 PM
Template can be nested. Example: Your user name is << << username >> >>. It means, Key username has value param1, Key param1 has value is barcelona so the final result will be: Your user name is Barcelona.
My classes and interfaces:
RenderContext.java
public interface RenderContext {
public String getParameter(String key);
}
MessageRenderer.java
public interface MessageRenderer {
public String render(String s, RenderContext... context);
}
MethodExpressionEvaluator.java
// Using this class to implements the method evaluation, such as now(), now_locale()
public interface MethodExpressionEvaluator {
public String evaluate(String[] methodParams, RenderContext... context);
}
AbstractMessageRenderer.java
public abstract class AbstractMessageRenderer implements MessageRenderer {
public static final String DEFAULT_NULL = "###";
public static final String PLACEHOLDER_START_TOKEN = "<<";
public static final String PLACEHOLDER_END_TOKEN = ">>";
protected int lenPlaceholderStartToken = 0;
protected int lenPlaceholderEndToken = 0;
protected String nullToken;
protected String placeholderStartToken;
protected String placeholderEndToken;
protected boolean escape = true;
public AbstractMessageRenderer() {
placeholderStartToken = PLACEHOLDER_START_TOKEN;
placeholderEndToken = PLACEHOLDER_END_TOKEN;
lenPlaceholderStartToken = placeholderStartToken.length();
lenPlaceholderEndToken = placeholderEndToken.length();
nullToken = DEFAULT_NULL;
}
public String getNullToken() {
return nullToken;
}
public void setNullToken(String defaultNull) {
this.nullToken = defaultNull;
}
public String getPlaceholderStartToken() {
return placeholderStartToken;
}
public void setPlaceholderStartToken(String placeholderStartToken) {
this.placeholderStartToken = placeholderStartToken;
lenPlaceholderStartToken = placeholderStartToken.length();
}
public String getPlaceholderEndToken() {
return placeholderEndToken;
}
public void setPlaceholderEndToken(String placeholderEndToken) {
this.placeholderEndToken = placeholderEndToken;
lenPlaceholderEndToken = placeholderEndToken.length();
}
public boolean isEscape() {
return escape;
}
public boolean getEscape() {
return escape;
}
public void setEscape(boolean escape) {
this.escape = escape;
}
public String getParam(String key, RenderContext... context) {
if(context != null)
{
for(RenderContext param:context)
{
if(param != null)
{
String value = param.getParameter(key);
if(!StringUtil.isEmpty(value))
{
return value;
}
}
}
}
return nullToken;
}
public String render(String s, RenderContext... context) {
// handle trivial cases of empty template or no placeholders
if (s == null)
{
Log4j.app.debug("Message is null in template. Cannot render null message.");
return nullToken;
}
if (context == null)
{
Log4j.app.debug("RenderContext is null. Cannot render message with null RenderContext.");
return nullToken;
}
if (s.indexOf(placeholderStartToken) < 0)
{
return s;
}
String msg = nullToken;
try
{
// private int renderTemplate(Renderable r, String src, StringBuffer dst, String nil, int i, String[] marks, StringBuffer end,boolean escapes)
msg = doRender(s, context);
}
catch (Exception e)
{
Log4j.app.error("Exception in rendering template: " + e.getMessage(), e);
return nullToken;
}
return msg;
}
protected abstract String doRender(String s, RenderContext... context);
}
MethodExpressionRenderer.java
public class MethodExpressionRenderer extends AbstractMessageRenderer {
private boolean inSingleQuote = false;
private boolean inDoubleQuote=false;
private int placeholders;
private Stack<String> methodStack;
private String[] endTokens;
private String marker;
private List<String> methodParams;
private String prefix = "&";
public MethodExpressionRenderer() {
super();
methodStack = new Stack<String>();
marker = ",";
endTokens = new String[] { placeholderEndToken, marker, "(", ")" };
methodParams = new ArrayList<String>();
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getMarker() {
return marker;
}
public void setMarker(String marker) {
this.marker = marker;
endTokens = new String[] { placeholderEndToken, marker };
}
#Override
public void setPlaceholderEndToken(String placeholderEndToken) {
super.setPlaceholderEndToken(placeholderEndToken);
endTokens = new String[] { placeholderEndToken, marker };
}
protected String doRender(String s, RenderContext... context) {
StringBuffer sb = new StringBuffer();
try
{
renderTemplate(s, sb, nullToken, 0, endTokens, null, context);
}
catch (Exception e)
{
Log4j.app.error("Exception in rendering method expression message emplate: " + e.getMessage(), e);
return nullToken;
}
return sb.toString();
}
private int renderTemplate(String src, StringBuffer dst, String nil, int i, String[] marks, StringBuffer end, RenderContext... context) {
int len = src.length();
while (i < len)
{
char c = src.charAt(i);
if (escape)
{
if (c=='\\')
{
i++;
char ch = src.charAt(i);
if(inSingleQuote)
{
if(ch=='\'')
{
inSingleQuote=false;
}
}
else if(inDoubleQuote)
{
if(ch=='"')
{
inDoubleQuote=false;
}
}
else
{
if(ch=='\'')
{
inSingleQuote=true;
}
else if(ch=='"')
{
inDoubleQuote=true;
}
}
dst.append(ch);
i++;
continue;
}
}
if(inSingleQuote)
{
if(c=='\'')
{
inSingleQuote=false;
}
}
else if(inDoubleQuote)
{
if(c=='"')
{
inDoubleQuote=false;
}
}
else
{
if(c=='\'')
{
inSingleQuote=true;
}
else if(c=='"')
{
inDoubleQuote=true;
}
}
// check for end marker
if (marks != null && !inSingleQuote && !inDoubleQuote)
{
for (int m = 0; m < marks.length; m++)
{
// If one of markers found
if (src.regionMatches(i, marks[m], 0, marks[m].length()))
{
// return marker if required
if (end != null)
{
end.append(marks[m]);
}
return i+marks[m].length();
}
}
}
// check for start of placeholder
if (src.regionMatches(i, placeholderStartToken, i, lenPlaceholderStartToken))
{
synchronized(this)
{
++placeholders;
}
i = renderPlaceholder(src, dst, nil, i, new ArrayList<String>(), context);
continue;
}
// just add plain character
if(c != '\'' && c!= '"')
{
dst.append(c);
}
i++;
}
return i;
}
private int renderPlaceholder(String src, StringBuffer dst, String nil, int i, List<String> params, RenderContext... context){
StringBuffer token = new StringBuffer(); // placeholder token
StringBuffer end = new StringBuffer(); // placeholder end marker
String value;
i = renderTemplate(src, token, nil, i+lenPlaceholderStartToken, endTokens, end);
String sToken = token.toString().trim();
String sEnd = end.toString().trim();
boolean isFunction = sEnd.equals("(");
// This is method name
if(isFunction && placeholders > methodStack.size())
{ // Method
synchronized(this)
{
methodStack.push(sToken); // put method into stack
}
}
else if(!isFunction && (methodStack.size()==0) && sEnd.equals(placeholderEndToken)) // Single template param such as <<param>>
{
value = getParam(sToken, context);
if(value != null)
{
if(value.trim().startsWith(placeholderStartToken))
{
value = render(src, context);
}
dst.append(value);
return i;
}
}
// TODO: Process method parameters to invoke
//.... ?????????
// Found end method token ')'
// Pop method out of stack to invoke
if ( (methodStack.size() >0) && (sEnd.length() == 0 || sEnd.equals(")")))
{
String method = null;
synchronized(this)
{
// Pop method out of stack to invoke
method = methodStack.pop();
--placeholders;
dst.append(invokeMethodEvaluator(method, methodParams.toArray(new String[0]), context));
methodParams.clear();
}
}
return i;
}
// Currently this method just implement to test so it just printout the method name
// and its parameter
// We can register MethodExpressionEvaluator to process
protected String invokeMethodEvaluator(String method, String[] params, RenderContext... context){
StringBuffer result = new StringBuffer();
result.append("[ ")
.append(method)
.append(" ( ");
if(params != null)
{
for(int i=0; i<params.length; i++)
{
result.append(params[i]);
if(i != params.length-1)
{
result.append(" , ");
}
}
}
result.append(" ) ")
.append(" ] ");
return result.toString();
}
}
We can easily register more method to the renderer to invoke. Each method will be an object and can be reused. But I'm in trouble how to resolve the nested method parameter. Can anyone give me an advice how we can process nested template of method parameter to invoke??? The line has TODO. Will my code in on the right way???
When you evaluate something like << count( << getTransId() >> ) >> you can either:
perform direct-evaluation as you parse, and push each function onto a stack, so that once you've evaluated getTransId() you pop the stack and use the return value (from the stack) as an argument for count(), or
you can build a parse tree to represent all the function calls that will be made, and then evaluate your parse tree after building it. (Building a tree probably doesn't buy you anything; since you're writing a template engine there is probably no high-level tree operation 'optimizations' that you could perform.)
An excellent little book I really enjoyed was Language Implementation Patterns by Parr. He walks through building simple to complex languages, and covers decisions like this in some depth. (Yes, he uses the ANTLR parser generator throughout, but your code looks like you're familiar enough with hand-generated parsers that different tools won't be a distraction for you.)
I found the bug and fixed it.
This is my new source:
// AbstractMethodExpressionRenderer.java
public class AbstractMethodExpressionRenderer extends AbstractMessageRenderer {
private boolean inSingleQuote = false;
private boolean inDoubleQuote=false;
private Stack<MethodExpressionDescriptor> functionStack;
private String[] endTokens;
private String marker;
private String prefix = "~";
public AbstractMethodExpressionRenderer() {
super();
functionStack = new Stack<MethodExpressionDescriptor>();
marker = ",";
endTokens = new String[] { placeholderEndToken, "(", ")", };
}
private class MethodExpressionDescriptor {
public List<String> params;
public String function;
public MethodExpressionDescriptor() {
params = new ArrayList<String>();
}
public MethodExpressionDescriptor(String name) {
this();
this.function = name;
}
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getMarker() {
return marker;
}
public void setMarker(String marker) {
this.marker = marker;
endTokens = new String[] { placeholderEndToken, marker };
}
#Override
public void setPlaceholderEndToken(String placeholderEndToken) {
super.setPlaceholderEndToken(placeholderEndToken);
endTokens = new String[] { placeholderEndToken, marker };
}
protected String doRender(String s, RenderContext... context) {
StringBuffer sb = new StringBuffer();
try
{
renderTemplate(s, sb, nullToken, 0, endTokens, null, context);
}
catch (Exception e)
{
Log4j.app.error("Exception in rendering method expression message emplate: " + e.getMessage(), e);
return nullToken;
}
return sb.toString();
}
private int renderTemplate(String src, StringBuffer dst, String nil, int i, String[] marks, StringBuffer end, RenderContext... context) {
int len = src.length();
while (i < len)
{
char c = src.charAt(i);
if (escape)
{
if (c=='\\')
{
i++;
char ch = src.charAt(i);
if(inSingleQuote)
{
if(ch=='\'')
{
inSingleQuote=false;
}
}
else if(inDoubleQuote)
{
if(ch=='"')
{
inDoubleQuote=false;
}
}
else
{
if(ch=='\'')
{
inSingleQuote=true;
}
else if(ch=='"')
{
inDoubleQuote=true;
}
}
dst.append(ch);
i++;
continue;
}
}
if(inSingleQuote)
{
if(c=='\'')
{
inSingleQuote=false;
}
}
else if(inDoubleQuote)
{
if(c=='"')
{
inDoubleQuote=false;
}
}
else
{
if(c=='\'')
{
inSingleQuote=true;
}
else if(c=='"')
{
inDoubleQuote=true;
}
}
// check for end marker
if (marks != null && !inSingleQuote && !inDoubleQuote)
{
for (int m = 0; m < marks.length; m++)
{
// If one of markers found
if (src.regionMatches(i, marks[m], 0, marks[m].length()))
{
// return marker if required
if (end != null)
{
end.append(marks[m]);
}
return i+marks[m].length();
}
}
}
// check for start of placeholder
if (src.regionMatches(i, placeholderStartToken, 0, lenPlaceholderStartToken))
{
i = renderPlaceholder(src, dst, nil, i, new ArrayList<String>(), context);
continue;
}
// just add plain character
if(c != '\'' && c!= '"')
{
dst.append(c);
}
i++;
}
return i;
}
/**
* Render a placeholder as follows:
*
* <<key>>: Simple render, key value map
* <<function(<<param1>>, <<param2>>)>> : Function object render
*
* #param src
* #param dst
* #param nil
* #param i
* #param params
* #param context
* #return
*/
private int renderPlaceholder(String src, StringBuffer dst, String nil, int i, List<String> params, RenderContext... context){
StringBuffer token = new StringBuffer(); // placeholder token
StringBuffer end = new StringBuffer(); // placeholder end marker
String value = null;
// Simple key
i = renderTemplate(src, token, nil, i+lenPlaceholderStartToken, endTokens, end, context);
String sToken = token.toString().trim();
String sEnd = end.toString().trim();
// This is method name
if(sEnd.equals("("))
{ // Method
functionStack.add(new MethodExpressionDescriptor(sToken));
}
else // Try to resolve value
{
if(sToken.startsWith(placeholderStartToken))
{
value = render(sToken, context);
}
else if(sToken.startsWith(prefix))
{
if(functionStack.size() > 0)
{
functionStack.peek().params.add(sToken.substring(1));
}
return i;
}
else
{
value = getParam(sToken, context);
}
}
if (sEnd.length() == 0 || sEnd.equals(placeholderEndToken))
{
// No method found but found the end of placeholder token
if(functionStack.size() == 0)
{
if(value != null)
{
dst.append(value);
}
else
{
dst.append(nil);
}
}
else
{
functionStack.peek().params.add(value);
}
}
else
{
if(value != null)
{
value = value.trim();
}
if(end.substring(0, 1).equals("(") ||
end.substring(0, 1).equals(marker))
{
// right hand side is remainder of placeholder
StringBuffer tmp = new StringBuffer();
end = new StringBuffer();
i = renderTemplate(src, tmp, nil, i, endTokens, end, context);
}
if(end.substring(0, 1).equals(")"))
{
if ( functionStack.size() > 0 )
{
// Pop method out of stack to invoke
MethodExpressionDescriptor descriptor = functionStack.pop();
if(functionStack.size() > 0 )
{
functionStack.peek().params.add(invokeMethodEvaluator(descriptor.function, descriptor.params.toArray(new String[0]), context));
}
else
{
dst.append(invokeMethodEvaluator(descriptor.function, descriptor.params.toArray(new String[0]), context));
}
end = new StringBuffer();
StringBuffer tmp = new StringBuffer();
i = renderTemplate(src, tmp, nil, i, endTokens, end, context);
}
}
}
return i;
}
protected String invokeMethodEvaluator(String method, String[] params, RenderContext... context){
StringBuffer result = new StringBuffer();
result.append("[ ")
.append(method)
.append(" ( ");
if(params != null)
{
for(int i=0; i<params.length; i++)
{
result.append(params[i]);
if(i != params.length-1)
{
result.append(" , ");
}
}
}
result.append(" ) ")
.append(" ] ");
return result.toString();
}
}