How to properly get a Collection out of an Entity using getProperty() - java

When I put an ArrayList into an Entity using setUnindexedProperty(), how does it come back out?
I'm doing this:
Collection<Key> keys = (Collection<Key>) entity.getProperty(propName);
And I get this warning:
warning: [unchecked] unchecked cast
found : java.lang.Object
required: java.util.Collection<com.google.appengine.api.datastore.Key>
Collection<Key> keys = (Collection<Key>) entity.getProperty(propName);
Is this the best I can do? Is there at least a way to get rid of the warning?
UPDATE: I do not get this warning on other entity.getProperty() calls that return an object that I downcast to, say a String or a Blob.

entity.getProperty() returns an Object. It has no way of knowing what you're actually putting in or getting out, so it's always going to warn you unless you #SuppressWarnings. If you aren't comfortable doing it this way you have to use something like Objectify/Twig/JDO instead of the native datastore.

You can use the following annotation to ignore the unchecked cast warning.
#SuppressWarnings("unchecked")
But that assumes that you want to suppress the warnings rather than to fix the issue that it complained about.

Related

Serializing / deserializing optionals with Morphia

I need Morphia to support serialization of java 8 Optional. Morphia clearly doesn't special case Optional, and, by default, Morphia seems to serialize an Optional with a value to {value: BLAH} and to drop an empty Optional (as I have dropEmpty or whatever configured).
When I attempt to rehydrate an Optional containing an enum though, Morphia fails with a class cast exception in the bowels of the mapping logic:
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to com.mongodb.DBObject
at org.mongodb.morphia.mapping.EmbeddedMapper.fromDBObject(EmbeddedMapper.java:160)
Indeed, Morphia seems to be losing type information; when I implemented my own TypeConverter, the MappedField contained no subClass information, which is where I'd normally look for information for the information. Instead, I had to store class information about the inner value in a separate field so that the result ends up looking like:
{"valueClassName" : "full.class.name" "value" : BLAH}.
Is there a more elegant way of handling this? This pretty much seems like a special case of IterableConverter (although that clearly depends on the subClass value being present within MappedField as well.
For what it's worth, 'upgrading morphia' isn't much of an option, because of the myriad bugs that erupt whenever we try to do so. This was failing with org.mongodb.morphia version 0.108

Bukkit Config - get Subsections and safe casting

I have the following config file:
arenas
arena1
info: infotest
info2: info2test
arena2
info: infotest
info2: info2test
So. Now i want to get one arena, and convert it to a arena object, i have a constructor there taking a Map. So i do following:
Arena a = new Arena((Map<String, Object>) getConfig().get("arenas.arena1"));
That is working. But: im getting the following warning in eclipse:
Type safety: Unchecked cast from Object to Map<String,Object>
I undestand why this apperas. but how can i change the way getting the informations to avoid this, so to make a "safe" cast?
And my second question: Now i want to get all the sub Map 's from arenas.""
and initialize them when the plugin loads. How can i get all of them? I cannot find something like arenas.getAll() or i dont know.. something like this.. anyone an idea?
Thank you.
For your first question, you can get the configuration section "arena1" and get all of the values as a Map without any warnings. To do this, use:
config.getConfigurationSection("arenas.arena1").getValues(false);
Alternatively, you can just put #SupressWarnings("unchecked") over the method where you're using that code. Since you know the type you're getting will be a Map, the warning doesn't really mean much, though some developers might consider this bad practice.
For your second question, you can use a similar method. getValues() is essentially a getAll() type of method, it gets a map of all of the keys and values in the section. So you could use:
config.getConfigurationSection("arenas").getValues(false);

How to remove 'Type Safety'/'Unchecked conversion' warning from returning generic List in Java?

I'm performing the following operation in Java using Hibernate inside my data access object:
public List<Device> getDevices() {
return getCurrentSession().createQuery("from Device").list();
}
This gives me the following warning:
Type safety: The expression of type List needs unchecked conversion to conform to List<Device>
In order to remove the warning I'm using
#SuppressWarnings("unchecked")
but I'm looking for a better way to remove this warning and ideally deal with something other than 'Device' from being returned from the database.
Any ideas?
Java does not have reified generics, so sadly you can not get rid of the annotations :(
If you search for this on SO, one of the most often recommended solutions is to use Collections.checkedList, which might be helpful here
Since you put the spring tag in your question I assume that you are already using Spring. In that case using SpringData and JPA instead of Hibernate-specific stuff would be much easier. Otherwise you can't really get rid of the warning because you can't change the api.
The hibernate session object will not return a typed Query. You can utilize an EntityManager instead (which hibernate supports), which does allow you to specify type on createQuery().

How to overcome type safety warning without ignoring it in eclipse?

I am getting warning from eclipse
Type safety: The expression of type TreeItem[] needs unchecked conversion to conform to TreeItem<AppleItem>[]
while using this:
TreeItem<AppleItem>[] friends = item.getChildren().toArray(new TreeItem[0]);
I dont want to use #uncheck or I dont want to use a loop for inserting one by one. Is there a way to do this?
Appearantly getChildren returns an ArrayList like ArrayList<TreeItem<AppleItem>>
Thanks in advance.
Nope, there's no way to do it without an unchecked cast. #Ivaylo's solution won't save you from casting, either.

Unexpected behaviour of diamond interface in JDK7

I have a property in my JSF managed bean:
private List<Long> selectedDataSets;
I initialize the list like this within an other method:
ArrayList<Long> longList = new ArrayList<>();
What happens is I get java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Long right when it jumps on this foreach:
for (Long CRC : selectedDataSets) { ... }
Which is very odd. Debug shows that selectedDataSets are full of String values, but I thought that's not even possible. Please describe me what exactly happened here.
Apparently you bound the property to an UISelectMany component like <h:selectManyCheckbox> or <selectManyListbox> without explicitly specifying a Converter. In Java, the generic type is erased during runtime and JSF (more specifically, EL) does not know anything about the generic list type at all and defaults to String unless told otherwise by a Converter. It's String because that's just the default value type of HttpServletRequest#getParameterMap(). EL fills the list with submitted values by reflection and does not take any generic types into account.
So, for example this should do it for you, with help of the builtin LongConverter:
<h:selectManyCheckbox value="#{bean.selectedDataSets}" converter="javax.faces.Long">
See also:
Use enum in h:selectManyCheckbox
Note that this has nothing to do with Java 7's diamond operator. You would have exactly the same problem when you have experimented with new ArrayList<Long>().

Categories

Resources