-
1. Persisting java.util.Map with custom class as key and value
wdfink Apr 17, 2011 2:22 PM (in response to piotrekde)Mmmh,
you are right, @ElementCollection is a EJB3.1 annotation (ähm a JPA2.0 which is part of EJB3.1).
ATM I have this options:
- store as a BLOB (MAP and its elements must be serializable)
- write your own mapper to store (and respect the EJB3.1 structure to port later )
- use a table with relation to store it
-
2. Re: Persisting java.util.Map with custom class as key and value
piotrekde Apr 20, 2011 3:53 PM (in response to wdfink)Thanks for help!
I think that the first one option is the easiest one (blob). Can I store object as a blob in a database, but have it defined as a Map type in class properties? What I mean is this (MyEntity class, myBlobMap property):
@Local public static interface MyEntityRepository { void persist(MyEntity entity); MyEntity find(long id); } @Stateful public static class MyEntityRepositoryBean implements MyEntityRepository { @PersistenceContext(unitName = "mydb") private EntityManager entityManager; public void persist(MyEntity entity) { entityManager.persist(entity); } public MyEntity find(long id) { return entityManager.find(MyEntity.class, id); } } @Entity @Table(name = "my_entity") private class MyEntity { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id") private long id; @Lob @Column(name="my_blob") private Map<CustomClassA, CustomClassB> myBlobMap; public MyEntity() { this.myBlobMap = new LinkedHashMap<CustomClassA, CustomClassB>(); } public long getId() { return this.id; } public void putToMap(CustomClassA a, CustomClassB b) { this.myBlobMap.put(a,b); } public Map<CustomClassA, CustomClassB> getMyBlobMap() { return this.myBlobMap; } } private class CustomClassA implements Serializable { private double a; private double b; public CustomClassA(double a, double b) { this.a = a; this.b = b; } public double getA() { return this.a; } public double getB() { return this.b; } } private class CustomClassB implements Serializable { private String x; public CustomClassB(String x) { this.x = x; } public String getX() { return this.x; } }
anyway, if I try to test this code, I'm getting an exception:
@Test public void testBlobPersistence() throws Exception { MyEntityRepository repo = (MyEntityRepository) initialContext.lookup( "MyEntityRepositoryBeanLocal"); MyEntity entity = new MyEntity(); //entity.putToMap(new CustomClassA(1,2), new CustomClassB("qwertyz")); repo.persist(entity); MyEntity persisted = repo.find(entity.getId()); //assertNotNull(persisted.getMyBlobMap()); }
(...)
Caused by: java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to java.sql.Blob
(...)
Do I have to store it as a blob internally? I found the similar issue here:
( #findBlob:HashMap)
-
3. Re: Persisting java.util.Map with custom class as key and value
wdfink Apr 21, 2011 4:32 AM (in response to piotrekde)In that case you have to write a hibernate mapper for this:
1)
Add annotation to your field => @org.hibernate.annotations.Type(type = "my.MapTypeBlobUserType")
2)
Write the mapper class my.MapTypeBlobUserType
implementing => org.hibernate.usertype.UserType
-
4. Persisting java.util.Map with custom class as key and value
piotrekde May 7, 2011 5:21 AM (in response to wdfink)Thanks, you are right.
However after thinking a while, I decided to split entities into couple of separate classes - it allows to map them into DB without using user types (a lot easier for me)