2

I have something like this:

@Entity
public class CallCardAttribute implements Serializable, IEntity {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String type;;
@Column(nullable = false)
@ManyToOne(optional = false)
private Validator validator;

public CallCardAttribute() {}
...

This class represents a single attribute of a CallCard. Since there can be many of them and the number can be different for any single one, I am storing the Attributes as a Map<Attribute, String>. To keep it in just one table, all the values are converted to Strings, regardless of the Java type in the application itself.

But when loading them from the database, I need to cast them to the right type. So I store it as the type parameter in the Attribute class as a Class name string.

I've figured out that I could use reflection to get an instance of the Class specified by the string and than fill it with the value.

Like in this snippet:

Integer i = 17;
String iVal = i.toString();
String iType = i.getClass().getName();

Object reVal = Class.forName(iType).newInstance();

But I need to cast reVal to the correct type, which can be any of String/Calendar/Integer/Double...

Can this be done? And if so, how?

5
  • In your snippet, "reVal" is a java.lang.Class type. How would you cast "reVal" from a java.lang.Class to a java.lang.String if the types are incompatible? It seems like an invalid question to me, can you clarify this? Commented Jan 18, 2012 at 18:13
  • 1
    "keep it in just one table," Why? Commented Jan 18, 2012 at 18:14
  • Reflection should be used judiciously, its uses has a bad impact on performance Commented Jan 18, 2012 at 18:20
  • Edited and hopefully fixed. As for the one table thing - it's modelled this way and I can't change that. Aside from that, if the value was stored as different types, how would it be mapped by the JPA? Commented Jan 18, 2012 at 18:21
  • It would be mapped according to the mapping provided by you in your Entity (if you use OneToMany) or in your Embeddable (if you use ElementCollection). Commented Jan 18, 2012 at 19:58

2 Answers 2

0

use instanceof to determine which to cast to: if (reVal instanceof String) result = (String) eval; ... You'll need a separate variable of each type to cast to

Sign up to request clarification or add additional context in comments.

Comments

0

If you don't want to use @OneToMany on the attribute collection you can use a JPA 2.0 ElementCollection.

http://en.wikibooks.org/wiki/Java_Persistence/ElementCollection

You'll still end up with attribs in a separate table.

3 Comments

So, can I map something like Map<Attribute, T> using JPA? Where T is any of String/Calendar/numbers?
yes, see for instance hwellmann.blogspot.com/2010/07/jpa-20-mapping-map.html or google "jpa map elementcollection onetomany" ... but it won't work for you if you can only use one table. Edit: And T can't be just any Object, it must be of the type you have annotated with Embeddable or Entity.
Maybe you could serialize/deserialize to a blob and cast using instanceof after deserialization. But it'd also require a change of the schema (and it'd be pretty nasty in general). stackoverflow.com/questions/2121860/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.