How to map an EnumMap to a cassandra column? - java

I need to map an EnumMap to a cassandra data column. The entity class looks like this:
#Table
class ContainingEnumMap {
#PrimaryKey
String key;
#Column
Map<SomeEnum, String> map;
}
If i register an EnumNameCodec, the instances of the above class are properly written to the database, however, if they are read back, i get a ClassCastException, as the map keys are in fact Strings.
If i explicitly use an EnumMap attribute, i get similar exceptions, as the keys are still Strings (and not enum instances).
Trying to annotate the map column with
#CassandraType(type = DataType.Name.MAP)
did not lead anywhere, as there are no proper DataType.Name constants for enums.
Is there a way to achieve this?

Related

Mapping a complex Map in JPA

i just can't obtain a persistence with an entity which has a field like this:
private Map<String, List<String>> filterValueRange;
i've tried so far:
#ElementCollection
#JoinTable(name="ATTRIBUTE_VALUE_RANGE", joinColumns=#JoinColumn(name="ID"))
#MapKeyColumn (name="Filter_Id")
#Column(name="FILTER")
private Map<String, List<String>> filterValueRange;
But it seems there is still something missing.
Can anybody point me to the right direction?
I'm using jpa as interface, but there's Hibernate under the hood.
thanks!
Mapping nested collection relationship is not supported with JPA however you can easily overcome this by changing the object model a little, for example:
#OneToMany(mappedBy = "parent")
#MapKeyColumn (name="Filter_Id")
private Map<String, ValueRange> filterValueRange;
and in the corresponding ValueRange entity:
#ManyToOne
private Parent parent;
Alternatively you may also take a look at the following post:
JPA Map<String,String[]> mapping
I don't believe it is possible. What you are trying to achieve is to map element collection of element collections.
In case I am wrong, you should use the
#CollectionTable annotation to define your jointable.
But I think you need to define Embedable that represent value range and has its own ElementCollection of values. Than you can map this embedable to your filterValueRange and access the list of values through it.
If you don't need to query by your filterValueRange you can serialize it simply to Blob.

How to persist a map inside a map in Hibernate?

So I have a class similar to this
public class MyClass{
...
#ElementCollection
private Map<Long,Map<Long,Double>> Vs = new HashMap<Long, Map<Long,Double>>();
...
}
This returns an error when I try to persist the class:
org.hibernate.MappingException: Could not determine type for: java.util.Map, at table: MyClass_Vs, for columns: [org.hibernate.mapping.Column(Vs)]
I think the error is because there is a map inside the original map that has the annotation of #ElementCollection. Any idea of how to solve this?
I really doubt Hibernate will be able to handle this type of mapping for you with just #ElementCollection. You probably will need to define a new composite key, containing both of those Long map keys as #Id fields, then use an element collection on a Map<CompositeLong, Double>. Granted, I'm making some assumptions about what those Long values represent, but it's hard to tell without more context.

Hibernate: Obtaining Map with a column's value as "key", and as "value" a list of rows containing "key"

Good afternoon,
I have the following entity:
#Entity(name = "t_test")
public class Test {
private int id;
private String name;
private String type;
....
I basically want to create a query/criteria that returns just one Map, where the keys are the distinct values of Test.type, and the values of the map are Lists of Test objects with the corresponding type property.
E.g: Map>
Can this be done in one query? Right now I'm just fetching everything and creating the map by code.
Thanks in advance!
You could write a ResultTransformer to create and return the map, but it wouldn't be much different than what you're doing now. The code would just be in a different place.
To produce the Map<String, List<Test>>, you need to load all the test entries from the database anyway. There's no processing related to the map creation that can be moved closer to the DB except maybe ordering by type. You basically have to make the map in your code.

Hibernate mapping a UserType inside a Map

I have come across a problem where I cannot persist a Map<UUID, Integer> using Hibernate. I'm not sure how to properly annotate this collection such that it may be properly mapped into our database. We control the schema, so any way this will work will be fine. Do i need to specify what UserType the key is in my Map somehow? Do I need one? I know the Type annotation is used for individual fields. Perhaps not collections? I am receiving the following exception on my call to session.flush()
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.UUID
#ElementCollection
#Type(type="org.hibernate.type.UUIDCharType")
private Map<UUID, Boolean> orderCount = new HashMap<UUID, Integer>();
I believe you will have to write a UserType to handle Map<UUID, Boolean> .. This UserType should then use org.hibernate.type.UUIDCharType to map the key column.

Is it possible to have a hashmap with 4 objects?

Can I have an hashMap with say ID as my key and info, name, quantity as my values?
ok, say I have a class (Products) already that sets my variables, getters and setters. In my Invoice class, which is where the hashMap would be. Would I put like:
private HashMap<String, Products> keys = new HashMap<String, Products>
I'm not quite sure how to access the HashMap though. Say I implement a class that allows me to add and remove invoices from the HashMap, I do not know what the values would be:
keys.put(??value of id??,??not sure what goes here??);
Sure. Make another class that contains your info, name and quantity and put that as the value of your HashMap.
No, but the best way is to wrap the information you want to keep in the map in a class:
public class Info {
private String info;
private String name;
private int quantity;
...
public Info(String info, String name, int quantity) {
...
}
}
Then do this to put something in the map:
Info info = new Info("info", "name", 2);
Map map = new HashMap<Integer, Info>();
map.put(22, info);
And do this to get something out:
Info info = map.get(22)
How about HashMap<Integer, ArrayList<String>> ?
UPDATE: Please try to avoid this, this is a better approach.
Not exactly.
A Map defines a strictly 1 to 1 relationship between keys and values. One key in the map has one value.
If you want to associate multiple values with one key you need to do one of the following:
Define a Values class to represent the values as a single object; e.g. as per #Starkey's and #Javed's answers. Then the map becomes a Map<String, Values> (assuming that the key type is String).
Define the map as a Map<String,List<Object>> or Map<String,Object[]> and represent the values as an untyped list / array
Define the map as a Map<String,Properties> or Map<String,Map<String,Object>> and represent the values as the Java equivalent of an associative array.
Of these, the first option is both the safest (smallest chance of runtime errors), the most efficient and the best style.
(Aside: an Apache commons MultiMap might be considered as another possibility, but the conceptual model and APIs don't really match this use-case.)
Sure. Depending on how flexible your datastructe is you can use a Hashmap a la:
HashMap<IdType, List<String>>, with IdType String or Integer, depending on the Keys you like to use.
HashMap<IdType, String[]>
HashMap<IdType, YourObjectType>, with YourObjectType beeing a Object you defined yourself, holding the values you like
YourObjectType can of course be anything you can define as an Object. Also another HashMap if you like.
One of the concerns while using a Map would be use of hardcoded keys. If the key is a string, and the key changes. Can consider using a constant instead of a hardcoded string.
Having a dedicated class has the benefit of compiler to check for name changes. However, as mentioned in the earlier comments.. It can become a concern...
In my opinion both are feasible. We need to weigh which option is better depending on the situation
Create an object that encapsulates the four together. Something like:
public class Foo {
private String s1;
private String s2;
private int v3;
private MyObject obj1
// constructors, getters, helper functions.
}
I think MultiMap from google library could serve the purpose
https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Multimap.html
Multimap<String, String> map = ArrayListMultimap.create();
String key = "uniqueKey";
map.put(key, "value1");
map.put(key, "value2");
map.put(key, "value3");
System.out.println(map);//{uniqueKey=[value1, value2, value3]}
Of course, you could for example declare it like this: HashMap<Integer, HashMap<String,Object>> You use the outer hashmap to link your id with your inner HashMap, and in the inner one, you create keys "info", "name", "quantity" and associate values with them.
Of course, you could also use an ArrayList as the outer collection (it could be a better match for your ID: ArrayList<HashMap<String,Object>> that way you have indexed (id based) access to each of your "info", "name", "quantity" hashmap "records"
You could have ID as key and a List or Set (Collection in general) of objects as value.

Categories

Resources