Codenameone How to externalize the Location object - codenameone

I receive following error message when I try to add Location for externalization. Please advise how to externalize the Location object. Please advise.
See the code used for Storage and Externalization
code:
addOfflineCommand("location", latitude, longitude, time1);
latitude - double data type;
longitude - double data type;
time1 - long data type;
private void addOfflineCommand(String name, Object... args) {
List<OfflineCommand> l_noAppt = (List<OfflineCommand>)
Storage.getInstance().readObject(appName + user + "-offlineCommandsLocEnc");
l_noAppt.add(new OfflineCommand(name, args));
}
Please see the Error Message below:
[EDT] 0:4:37,444 - Exception: java.io.IOException - Object type not supported: com.codename1.location.Location value: altitude = 1000.0
latitude40.714353
longtitude-74.00597299999998
direction0.0
timeStamp1529000278457
velocity50.0
at java.io.DataInputStream.readFully(DataInputStream.java:197)
at java.io.DataInputStream.readUTF(DataInputStream.java:609)
at java.io.DataInputStream.readUTF(DataInputStream.java:564)
at com.codename1.io.Util.readObject(Util.java:562)
at com.codename1.io.Util.readObject(Util.java:595)
at com.X.Xmobile.server.OfflineCommand.internalize(OfflineCommand.java:40)
at com.codename1.io.Util.readObject(Util.java:689)
at com.codename1.io.Util.readObject(Util.java:664)
at com.codename1.io.Storage.readObject(Storage.java:261)
at com.X.Xmobile.server.ServerImpl.addOfflineCommand(ServerImpl.java:1165)
at com.X.Xmobile.server.ServerImpl.finishActivity(ServerImpl.java:1504)
at com.X.Xmobile.forms.CommentForm.lambda$new$3(CommentForm.java:70)
java.io.IOException: Object type not supported: com.codename1.location.Location value: altitude = 1000.0
latitude40.714353
longtitude-74.00597299999998
direction0.0
timeStamp1529000278457
velocity50.0
at com.codename1.io.Util.writeObject(Util.java:457)
at com.codename1.io.Util.writeObject(Util.java:394)
at com.X.Xmobile.server.OfflineCommand.externalize(OfflineCommand.java:34)
at com.codename1.io.Util.writeObject(Util.java:258)
at com.codename1.io.Util.writeObject(Util.java:286)
at com.codename1.io.Storage.writeObject(Storage.java:224)
at com.X.Xmobile.server.ServerImpl.addOfflineCommand(ServerImpl.java:1201)
at com.X.Xmobile.server.ServerImpl.finishActivity(ServerImpl.java:1504)
[EDT] 0:6:4,551 - Exception: java.io.IOException - Object type not supported: com.co
Following is the class OfflineCommand class created which is used for externalization.
public class OfflineCommand implements Externalizable {
private static final int VERSION = 1;
private String name;
private Object[] arguments;
public OfflineCommand() {}
public OfflineCommand(String name, Object... args) {
this.name = name;
this.arguments = args;
}
#Override
public int getVersion() {
return VERSION;
}
#Override
public void externalize(DataOutputStream out) throws IOException {
Util.writeUTF(name, out);
Util.writeObject(arguments, out);
}
#Override
public void internalize(int version, DataInputStream in) throws IOException {
name = Util.readUTF(in);
arguments = (Object[])Util.readObject(in);
}
#Override
public String getObjectId() {
return "OfflineCommand";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object[] getArguments() {
return arguments;
}
public void setArguments(Object[] arguments) {
this.arguments = arguments;
}
}

Location isn't externalizable. It doesn't support object serialization explicitly. Normally you would need to convert the write/read data to work with the location data instead of the location object. However, since your code is generic you would need to extend location to implement externalizable.
public class ExternalizableLocation extends Location implements Externalizable {
// implement the externalizable interface here...
}
In your init(Object) class register ExternalizableLocation as externalizable and in every place where you store a Location object replace it with ExternalizableLocation.

Related

Cant access nested list in Json response

Im trying to access some list items from a json response using retrofit but cant seem to be able to access using get method. The ListQuotes seems to be saying null
#JsonPropertyOrder({
"page",
"last_page",
"quotes"
})
public class ListQuoteResponse {
#JsonProperty("quotes")
private List<Quote> quotes = null;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
/**
* No args constructor for use in serialization
*
*/
public ListQuoteResponse() {
}
#JsonProperty("quotes")
public List<Quote> getQuotes() {
return quotes;
}
#JsonProperty("quotes")
public void setQuotes(List<Quote> quotes) {
this.quotes = quotes;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
But when I open the Quote class I am unable to access any of the properties
public class Quote {
#JsonProperty("id")
private Integer id;
#JsonProperty("dialogue")
private Boolean dialogue;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
/**
* No args constructor for use in serialization
*
*/
public Quote() {
}
#JsonProperty("id")
public Integer getId() {
return id;
}
#JsonProperty("id")
public void setId(Integer id) {
this.id = id;
}
#JsonProperty("dialogue")
public Boolean getDialogue() {
return dialogue;
}
#JsonProperty("dialogue")
public void setDialogue(Boolean dialogue) {
this.dialogue = dialogue;
}
I tried using
listQuoteBodyResponse.body().getQuotes() but that only returned random numbers and when I tried using the Quote class for the response directly like
QuoteResponse.body.getDialogue() its just returning null

Does Flink SQL support Java Map types?

I'm trying to access a key from a map using Flink's SQL API. It fails with the error Exception in thread "main" org.apache.flink.table.api.TableException: Type is not supported: ANY
Please advise how i can fix it.
Here is my event class
public class EventHolder {
private Map<String,String> event;
public Map<String, String> getEvent() {
return event;
}
public void setEvent(Map<String, String> event) {
this.event = event;
}
}
Here is the main class which submits the flink job
public class MapTableSource {
public static void main(String[] args) throws Exception {
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<EventHolder> mapEventStream = env.fromCollection(getMaps());
// register a table and use SQL
StreamTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env);
tableEnv.registerDataStream("mapEvent", mapEventStream);
//tableEnv.registerFunction("orderSizeType", new OrderSizeType());
Table alerts = tableEnv.sql(
"select event['key'] from mapEvent ");
DataStream<String> alertStream = tableEnv.toAppendStream(alerts, String.class);
alertStream.filter(new FilterFunction<String>() {
private static final long serialVersionUID = -2438621539037257735L;
#Override
public boolean filter(String value) throws Exception {
System.out.println("Key value is:"+value);
return value!=null;
}
});
env.execute("map-tablsource-job");
}
private static List<EventHolder> getMaps(){
List<EventHolder> list = new ArrayList<>();
for(int i=0;i<5;i++){
EventHolder holder = new EventHolder();
Map<String,String> map = new HashMap<>();
map.put("key", "value");
holder.setEvent(map);
list.add(holder);
}
return list;
}
}
When I run it I'm getting the exception
Exception in thread "main" org.apache.flink.table.api.TableException: Type is not supported: ANY
at org.apache.flink.table.api.TableException$.apply(exceptions.scala:53)
at org.apache.flink.table.calcite.FlinkTypeFactory$.toTypeInfo(FlinkTypeFactory.scala:341)
at org.apache.flink.table.plan.logical.LogicalRelNode$$anonfun$12.apply(operators.scala:530)
at org.apache.flink.table.plan.logical.LogicalRelNode$$anonfun$12.apply(operators.scala:529)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
at scala.collection.Iterator$class.foreach(Iterator.scala:742)
at scala.collection.AbstractIterator.foreach(Iterator.scala:1194)
at scala.collection.IterableLike$class.foreach(IterableLike.scala:72)
at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:245)
at scala.collection.AbstractTraversable.map(Traversable.scala:104)
at org.apache.flink.table.plan.logical.LogicalRelNode.<init>(operators.scala:529)
at org.apache.flink.table.api.TableEnvironment.sql(TableEnvironment.scala:503)
at com.c.p.flink.MapTableSource.main(MapTableSource.java:25)
I'm using flink 1.3.1
I think the problem lies in fromCollection. Flink is not able to extract the needed type information because of Java limitations (i.e. type erasure). Therefore you map is treated as black box with SQL ANY type. You can verify the types of your table by using tableEnv.scan("mapEvent").printSchema(). You can specify the type information in fromCollection with Types.MAP(Types.STRING, Types.STRING).
I solved a similar issue with the following:
//Should probably make MapVal more generic, but works for this example
public class MapVal extends ScalarFunction {
public String eval(Map<String, String> obj, String key) {
return obj.get(key);
}
}
public class Car {
private String make;
private String model;
private int year;
private Map<String, String> attributes;
//getters/setters...
}
//After registering Stream and TableEnv etc
tableEnv.registerFunction("mapval", new MapVal());
Table cars = tableEnv
.scan("Cars")
.select("make, model, year, attributes.mapval('name')");

camel jpa #Consumed is not being called

I'm trying to use #Consumed on jpa entity with camel.
this is my route :
<route id="incomingFileHandlerRoute">
<from
uri="jpa://com.menora.inbal.incomingFileHandler.Jpa.model.MessageToDB?consumer.nativeQuery=select
* from file_message where mstatus = 'TODO'&consumer.delay=5000&consumeDelete=false&consumeLockEntity=true&consumer.SkipLockedEntity=true" />
<to uri="bean:incomingFileHandler" />
</route>
and my entity:
#Entity
#Table(name = "file_message")
public class MessageToDB implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
private String uuid;
private String fileName;
private String body;
private String mstatus;
#Temporal(TemporalType.TIMESTAMP)
private Date mtimestamp;
#Consumed
public void updateMstatus() {
setMstatus(MessageStatus.DONE.name());
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getMstatus() {
return mstatus;
}
public void setMstatus(String mstatus) {
this.mstatus = mstatus;
}
public Date getMtimestamp() {
return mtimestamp;
}
public void setMtimestamp(Date mtimestamp) {
this.mtimestamp = mtimestamp;
}
}
I do get to incomingFileHandler bean with results from db but I do not get to the Consumed method updateMstatus . The incomingFileHandler bean is getting called continuously as always there are results from db
I have a similar implementation with camel-jpa and annotations #Consumed and #PreConsumed in the entity but none of these methods is called.
I look the camel-jpa source code and found this in JpaConsumer.java:
protected DeleteHandler<Object> createPreDeleteHandler() {
// Look for #PreConsumed to allow custom callback before the Entity has been consumed
final Class<?> entityType = getEndpoint().getEntityType();
if (entityType != null) {
// Inspect the method(s) annotated with #PreConsumed
if entityType is null the entity class inst inspect the method annotated with #Consumed and #PreConsumed.
Solution: add entityType=com.xx.yy.MessageToDB to your URI to set Endpoint Entity type.

how to read all date from PostgreSQL with array field jpa/hibernate ejb

i had problem to read all date from db PostgreSQL and jpa/hibernate ejb
my table has array field see below :
#Entity
public class MyTable{
private Long id;
private String name;
private String[] values;
#Type(type = "com.usertype.StringArrayUserType")
public String[] getValues(){
return values;
}
public void setValues(String[] values){
this.values = values;
}
}
and user type class like this :
package com.almasprocess.model.bl.en;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;
import java.io.Serializable;
import java.sql.*;
public class StringArrayUserType implements UserType {
protected static final int[] SQL_TYPES = { Types.ARRAY };
#Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return this.deepCopy(cached);
}
#Override
public Object deepCopy(Object value) throws HibernateException {
return value;
}
#Override
public Serializable disassemble(Object value) throws HibernateException {
return (String[]) this.deepCopy(value);
}
#Override
public boolean equals(Object x, Object y) throws HibernateException {
if (x == null) {
return y == null;
}
return x.equals(y);
}
#Override
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
#Override
public boolean isMutable() {
return true;
}
#Override
public Object nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor session, Object owner)
throws HibernateException, SQLException {
if (resultSet.wasNull()) {
return null;
}
if(resultSet.getArray(names[0]) == null){
return new Integer[0];
}
Array array = resultSet.getArray(names[0]);
String[] javaArray = (String[]) array.getArray();
return javaArray;
}
#Override
public void nullSafeSet(PreparedStatement statement, Object value, int index, SessionImplementor session)
throws HibernateException, SQLException {
Connection connection = statement.getConnection();
if (value == null) {
statement.setNull(index, SQL_TYPES[0]);
} else {
String[] castObject = (String[]) value;
Array array = connection.createArrayOf("varchar", castObject);
statement.setArray(index, array);
}
}
#Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
#Override
public Class<String[]> returnedClass() {
return String[].class;
}
#Override
public int[] sqlTypes() {
return new int[] { Types.ARRAY };
}
}
and read date like this in ejb class :
public List readMailBank(){
String query = "select mt from mytable mt";
TypedQuery<StringArrayUserType> typedQuery = em.createQuery(query , StringArrayUserType.class);
List<StringArrayUserType> results = typedQuery.getResultList();
return results;
}
or like this sample code :
public List readMailBank(){
Type stringType = (Type) new TypeLocatorImpl(new TypeResolver()).custom(StringArrayUserType.class);
Query query = em.createNativeQuery("select mt from mytable mt");
query.unwrap(SQLQuery.class).addScalar("mb", (org.hibernate.type.Type) stringType);
List<Mailbank>results = query.getResultList();
return results;
}
but i had this error :
Caused by: java.lang.IllegalArgumentException: Type specified for TypedQuery [com.usertype.StringArrayUserType] is incompatible with query return type [class [Ljava.lang.String;]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.resultClassChecking(AbstractEntityManagerImpl.java:387) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:344) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
at org.jboss.as.jpa.container.AbstractEntityManager.createQuery(AbstractEntityManager.java:131) [wildfly-jpa-8.2.0.Final.jar:8.2.0.Final]
please help me to read all data from db and fills array in to my array field?
thanks
I think the problem with your first example is that you try to create your query for values in Java which is a String[], but your JPQL asks for MyTable values. Which classes are not extending each other, thus you get an exception about the type incompatibility.
Something like
select mt.values from mytable mt
should give you what you want. (If it doesn't work at once, here is some documentation about selecting values instead of entities.)

Mixin annotation not getting honored when passed as a parameter

I have a third party class SpecialObject as:
public class SpecialObject {
private String name;
private Integer id;
private Date date;
public String getFoo() {return "foo";} //Outlier
public String getName() { return name;}
public Integer getId() {return id;}
public Date getDate() {return date;}
public void setName(String name) {this.name = name;}
public void setId(Integer id) {this.id = id;}
public void setDate(Date date) {this.date = date;}
}
I wish to only project out name and date properties when serializing it. Using the magic of MixinAnnotation from Jackson, I created a Mixin interface as:
#JsonAutoDetect(getterVisibility = Visibility.NONE)
public interface SpecialObjectMixin {
#JsonProperty
public String getName();
#JsonProperty
public Date getDate();
}
In order to facilitate handling of this SpecialObject as parameter, I have also defined a SpecialObjectHandler which implements the fromString() method.
#Override
public SpecialObject fromString(String json) {
try {
return objectMapper.readValue(json, SpecialObject.class);
} catch (IOException exception) {
throw new IllegalArgumentException("Unable to write JSON output",
exception);
}
}
When the deserializer invokes this method, the objectMapper throws an error as
Caused by: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "foo" (Class com.kilo.SpecialObject), not marked as ignorable
at [Source: java.io.StringReader#2d2217da; line: 1, column: 60] (through reference chain: com.kilo.SpecialObject["foo"])
at org.codehaus.jackson.map.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:53)
at org.codehaus.jackson.map.deser.StdDeserializationContext.unknownFieldException(StdDeserializationContext.java:267)
at org.codehaus.jackson.map.deser.std.StdDeserializer.reportUnknownProperty(StdDeserializer.java:673)
at org.codehaus.jackson.map.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:659)
at org.codehaus.jackson.map.deser.BeanDeserializer.handleUnknownProperty(BeanDeserializer.java:1365)
at org.codehaus.jackson.map.deser.BeanDeserializer._handleUnknown(BeanDeserializer.java:725)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:703)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2732)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1863)
at com.kilo.SpecialObjectHandler.fromString(SpecialObjectHandler.java:34)
My question is that is there a way that I can have the objectMapper (org.codehaus.jackson.map.ObjectMapper) also honor annotations from the Mixin where I had configured it to only deal with name and date? Feel free to point out something elementary that I may have overlooked. Thanks in advance!
It was a problem with configuration. The mixin was only set on the serialization config and not on the deserialization config causing the issue. Setting it on both configs solves the problem.

Resources