I am looking at this API ArrayListMultiMap which implements the Serializable interface. Does that mean I can serialize this object ? Are all Multimap objects serialized ?
The meaning of Serializable is always the same: If an object isn't serializable, it can't be serialized. If it is, it may work or not... Especially in case of collections (including maps and multimaps), it depends on their content.
As an example, you can surely serialize ArrayList<String> as ArrayList.class is serializable and so is each member of the list. OTOH trying to serialize ArrayList<Object> may or may not work: If all contained objects are e.g. strings, it will work. If any member is not serializable, you'll get an exception.
Does it mean I can serialize this object?
If all keys and values are serializable, you can.
Are all multiMap object serializable?
No, the interface Multimap doesn't extend Serializable, so there may be non-serializable implementation. Indeed, you can get such an instance via e.g. Multimaps.filterEntries.
ArrayListMultimap and HashMultimap are Serializable BUT the Collection views (in asMap() for example) are not.
This problem is answered here:
To use the map returned by asMap(), you can re-create a new map and wrap the Multimap Collection views into other collections (for example a Set), that will make the new map Serializable:
Multimap<MyClass, MyOtherClass> myMultiMap = HashMultimap.create();
// ... build your multimap
Map<MyClass, Set<MyOtherClass>> map = myMultiMap.asMap().entrySet()
.stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
(entry) -> ImmutableSet.copyOf(entry.getValue())
));
Or java 7 compliant code:
Multimap<MyClass, MyOtherClass> myMultiMap = HashMultimap.create();
// ... build your multimap
Map<MyClass, Set<MyOtherClass>> map = Maps.newHashMap();
for (Map.Entry<MyClass, Collection<MyOtherClass>> entry :
myMultiMap.asMap().entrySet()) {
map.put(entry.getKey(), ImmutableSet.copyOf(entry.getValue()));
}
Related
For example - I've got this entity:
class XdUser(entity: Entity) : XdEntity(entity) {
var someName by xdStringProp()
var someNumber by xdIntProp()
}
What is the proper way to serialize/deserialize it from/to json?
I have to create data class which just duplicates my entity's fields and then propagate values to XdUser? Or there is other way?
Serializing XdUser to JSON you should be sure that serializer won't process XdUser#entity and other public links which can expose large amount of unnecessary data. Deserialization brings another problems because deserializator should be informed about how to instantiate a class from json using constructor XdUser(entity: Entity).
From my prospective better choice there is to have another level for rest API. It brings ability to control amount of exposed data, control permissions (if your have them) and the way of how entities will be updated.
Rest api level be implemented like this:
open class EntityVO<T: XdEntity>(xdId: String?) {
}
class UserVO(xdId: String?): EntityVO<XdUser>(xdId: String?) {
var someName by delegateTo(XdUser::someName)
var someNumber by delegateTo(XdUser::someNumber)
}
and delegateTo should provide delegate which will lookup XdUser by xdId and do get/set value using specified XdUser property. For link/links logic will be more complex but idea can be the same.
I'm new to Kotlin, so apologies if I'm not articulating concepts correctly. I have an instance of an Entity
[TestEntity(applicationId=1, timestamp=2018-01-24T18:40:30, issueState=MA, product=test, status=sold, paymentMode=VISA, premium=null)]
I am writing a service that is going to take these keys and use them to create the headers of a report. The keys may change depending on the type of report the user is trying to generate, which will have an impact on the Entity that will be instantiated.
I want to be able to iterate over this Entity so that I can create an array to use for the headers. Any thoughts on how I do this?
I think the cleanest solution is storing values in a map and delegating properties to it.
Don't think you can otherwise iterate over class fields without some verbose getter chain or ugly reflection shenanigans.
For example here you can access map fields as if they were class fields, but can also easily iterate over map.
data class TestEntity(val map : Map<String, Any>){
val appId : Int by map
val timeStamp : Long by map
(... more fields)
}
In my Google Web Toolkit project, I got the following error:
com.google.gwt.user.client.rpc.SerializationException: Type ‘your.class.Type’ was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.
What are the possible causes of this error?
GWT keeps track of a set of types which can be serialized and sent to the client. your.class.Type apparently was not on this list. Lists like this are stored in .gwt.rpc files. These lists are generated, so editing these lists is probably useless. How these lists are generated is a bit unclear, but you can try the following things:
Make sure your.class.Type implements java.io.Serializable
Make sure your.class.Type has a public no-args constructor
Make sure the members of your.class.Type do the same
Check if your program does not contain collections of a non-serializable type, e.g. ArrayList<Object>. If such a collection contains your.class.Type and is serialized, this error will occur.
Make your.class.Type implement IsSerializable. This marker interface was specifically meant for classes that should be sent to the client. This didn't work for me, but my class also implemented Serializable, so maybe both interfaces don't work well together.
Another option is to create a dummy class with your.class.Type as a member, and add a method to your RPC interface that gets and returns the dummy. This forces the GWT compiler to add the dummy class and its members to the serialization whitelist.
I'll also add that if you want to use a nested class, use a static member class.
I.e.,
public class Pojo {
public static class Insider {
}
}
Nonstatic member classes get the SerializationException in GWT 2.4
I had the same issue in a RemoteService like this
public List<X> getX(...);
where X is an interface. The only implementation did conform to the rules, i.e. implements Serializable or IsSerializable, has a default constructor, and all its (non-transient and non-final) fields follow those rules as well.
But I kept getting that SerializationException until I changed the result type from List to X[], so
public X[] getX(...);
worked. Interestingly, the only argument being a List, Y being an interface, was no problem at all...
I have run into this problem, and if you per chance are using JPA or Hibernate, this can be a result of trying to return the query object and not creating a new object and copying your relavant fields into that new object. Check the following out, which I saw in a google group.
#SuppressWarnings("unchecked")
public static List<Article> getForUser(User user)
{
List<Article> articles = null;
PersistenceManager pm = PMF.get().getPersistenceManager();
try
{
Query query = pm.newQuery(Article.class);
query.setFilter("email == emailParam");
query.setOrdering("timeStamp desc");
query.declareParameters("String emailParam");
List<Article> results = (List<Article>) query.execute(user.getEmail
());
articles = new ArrayList<Article>();
for (Article a : results)
{
a.getEmail();
articles.add(a);
}
}
finally
{
pm.close();
}
return articles;
}
this helped me out a lot, hopefully it points others in the right direction.
Looks like this question is very similar to what IsSerializable or not in GWT?, see more links to related documentation there.
When your class has JDO annotations, then this fixed it for me (in addition to the points in bspoel's answer) : https://stackoverflow.com/a/4826778/1099376
I want to 'send' collection that contain numbers ( double ).
I try to add array to my DataContract but its fail ( thru exception .. when i remark the array type its work fine ).
How can i do it ?
Thanks for any help.
Collection Serialization happens automatically only when the collection in the contract is a concrete collection (that is, not an interface) and is serializable (annotated with the Serializable attribute). If that is the case, WCF can automatically serialize the collection as an array of the collection’s type as long as the collection contains an Add operation. This holds true for both the built-in .NET collections and for any of your own custom collections that implement the IEnumerable or IEnumerable interface; as long as they are serializable and have an Add operation, they can be serialized to arrays automatically.
If your collection does not meet these constraints specify the CollectionDataContractAttribute.
[CollectionDataContract(Name = "MyCollectionOf{0}")]
I have an object that maintains a property bag of various properties. This is exposed through my object model as a Dictionary<string, string> and is stored in the database as a JSON-encoded string.
What is the best way to map this class using Fluent NHibernate?
Option 1: Map to a private field, do JSON translation in my object?
Should I map the property to a private string field, and then do serialization to/from JSON in my object itself?
Pro: NH need only know about mapping a single string to a text column which seems easy enough.
Con: My model has to track the dictionary and a string, simply to support persistence.
Option 2: Use some sort of Interceptor?
I haven't done anything with NH Interceptors before, but I know of them. Could I use an interceptor to do the Dictionary/JSON serialization, so that my model need only know about the dictionary?
Option 3: Use a different encoding strategy?
Is there a different encoding strategy, besides JSON, that NH supports natively and that I could use to serialize my dictionary?
In order to store your Dictionary as a single encoded column, use a IUserType. You would map the dictionary as a property using your IUserType. This blog post has a good example of implementing an IUserType.
Map( x => x.JsonDictionary )
.CustomTypeIs<MyUserType>();
You can also map this as a collection of values. This allows querying of individual values from the dictionary.
HasMany( x => x.JsonDictionary )
.WithTableName("entity_jsondictionary")
.KeyColumnNames.Add("entityid")
.Cascade.All()
.AsMap<string>(
index => index.WithColumn("name").WithType<string>(),
element => element.WithColumn("value").WithType<string>()
);