How to define polymorphism in JPA - java

there is a situation. For example, I am designing simple blog. There are articles and photographies. Users can add their comment to both of them. So when I write it in Java, it looks like this:
public interface Commentable { ... }
public class Article implements Commentable { ... }
public class Photo implements Commentable { ... }
public class Comment {
...
private Commentable commentTo;
}
This is clear and I hope that design is correct. But now I would like to persist it in database and I want to use JPA annotations. Primarily I have to use JPA 1.0 but if there is not solution I would like to know how to do it in JPA 2.0. I found out that there is a way with classic inheritance but I think that Commentable shouldn't be a parent of these object, it is only extension in light of design.
Is there any way how to persist it without changing of desing, please? Thanks a lot

Is there any way how to persist it without changing of design, please? Thanks a lot
JPA doesn't really support your design (to be precise, you can map a relation pointing to an interface if there is a single implementation, but that's not your case). Your JPA provider might have some support for this though (e.g. EclipseLink has a #VariableOneToOne annotation).
With standard JPA, the usual approach would be to use an abstract class (with or without your interface) and to use inheritance. For example (keeping the interface):
public class Comment {
...
#OneToOne(targetEntity=MyAbstractBaseClass.class)
private Commentable commentTo;
}
Where both Article and Photo would extend MyAbstractBaseClass and implment the interface.
The JPA wikibook has two good sections on this topic, see below.
Resources
JPA Wikibook:
My relationship target is an interface
Variable and Heterogeneous Relationships

Related

Understanding Spring Data interfaces

I'm a little confused with some basic Spring Data concepts.
As I know, typical DAO level structure looks like this:
- dao
- MyFirstObjectDao
- MySecondObjectDao
- jpa
- MyFirstObjectDaoImpl
- jdbc
- MySecondObjectDaoImpl
With this concept, I can use JPA as implementation for my first DAO interface, and JDBC - for the second one.
Now i want to understand Spring Repository abstraction. Every Spring Data tutorial specifies, that I should have an interface, which should extends from JpaRepository, for example. So having this interface, i've already locked with JPA, right?
What if i want to provide different implementations, like jpa/jdbc in DAO?
There's normally not a very good reason to want to mix JPA and JDBC persistence for the same objects; if you're already annotating everything as JPA entities, you might as well use the same persistence setup everywhere. You ought to rethink why you're wanting to do this.
That said, you could potentially do this if you really needed to:
interface FooBaseRepository extends PagingAndSortingRepository<Long, Foo> {}
interface FooJpaRepository extends FooBaseRepository, JpaRepository<Long, Foo> {}
interface FooJdbcRepository extends FooBaseRepository, JdbcRepository<Long, Foo> {}
#Autowired FooBaseRepository surpriseRepository
Update: If you're just talking about having different persistence strategies for different classes (that don't have relationships), there's nothing particularly complicated. You could mix Jpa and Jdbc repositories; they're just interfaces.

Multiple Inheritance in Java - Spring Data

I want to create a DAO class named BaseDAO that should have the JPA and JDBC capabilities in Spring. I mean, I want to extend JPADAOSupport and JDBCDAOSupport classes of spring in to my BaseDAO class. I am aware that multiple inheritance is not an option in Java.
I have created two separate Base classes like BaseJPADao and BaseJdbcDao extending the respective classes. Is it possible to have a single class to extend both? Is there any design pattern solving this issue. Please advise.
Why don't you have a DaoGateway bean having injected the actual JPA DAO and the JDBC DAO beans.
This gateway can then decide which DAO to delegate a given request (to JPA or to JDBC).
You should always favour composition vs inheritance when reusing functionalities.
no it is not. if it was possible, you would still have the same result as in
one class extending JPADAOSupport and JDBCDAOSupport, which you yourself say you know is not possible because multiple inheritance is impossible.
you can write to an interface, and provide two implementations, though.
This would be easy to do with delegation if they both had interface level access you want:
public class MyUberClass implements WhateverJPADAOSupportDoes, WhateverJDBCDAOSupportDoes {
private JPADAOSuport jpa;
private JDBCDAOSupport jdbc;
// now implement all methods specified by the interfaces on the class signature and delegate to their respective member
}
But it seems you want access to all of their public methods. As there is no interface for both you can do the same as above but it can't be of both types simultaneously. The language expressly denies you this.
Your only other option is to create an adapter interface that your code can rely on and then use the combination delegation. If you're hoping to have one class that you can just drop in as a substitution for both then the answer is you can't.

Generic DAO disadvantages?

I want to create a DAO layer for my application. After some googling I found that many peoples uses Generic DAO approach (Don't repeat the DAO!).
But I did not like this approach.
What if I need slightly different interfaces between DAO for different DAO implementations? (i.e. methods in generic interface not exactly same which I want to create in my DAO implementations)
What if my entity's primary key consists of more than one attribute?
If you need a slightly different DAO for a particular entity, you can always extend a generic one(MySpecificDAO <....> extends GenericDAO<....>). Primary key can be composite itself, but it's impossible to have 2 primary keys .
Straight from the article you linked to:
Extending GenericDAO
The interface for each DAO is, of course, based on the GenericDao interface. I just need to adapt the interface to a specific domain class and extend it to include my finder methods. In Listing 6, you can see an example of the GenericDao interface extended for a specific purpose
Regarding your last question: by definition, an entity has one and only one primary key.
Disadvantage: you still have to implement the DAO. Stop following advice from 6 years ago, and use Spring Data repositories instead. Then you don't have to write any implementations at all.
What if I need slightly different interfaces between DAO for different
DAO implementations?
you can override the method in your GenericDaoImpl class. or create a new method.
What if my entity have 2 or more primary keys?
I guess you meant compound-key scenario. Note that usually the findOne/readOne/getOne method in GenericDao would expect a parameter, (T key) the T here is type, it could be composite primary key.
for example:
class PersonPK{
private String name;
private Date birthday;
.....
}
You can find here a Generic DAO a working and improved implementation of that very article. Just checkout the Example.java at the bottom of the page. In this example you can see how you can define "slightly different interfaces between DAO for different DAO
implementations".

How to "slice" a POJO

I'm borrowing the "slice" meaning from C++.
Let's say I hava a simple POJO that's persisted via Hibernate:
class Person {
private long id;
private String name;
...
// getters and setters here
...
}
Now, when I retrieve an object from the database I know it was "instrumented" by Hibernate (its real class is a Person-derived generated automatically). I want to convert it back to a "plain" person object. Tnat would be used, for instance, to submit the object to XStream and have the result containing only what Person contains.
I could do it by defining a copy constructor, but I don't want to have the hassle of having to write copy constructors for every ORM class (not to mention the violation of DRY principle).
So I was wondering if
a) is there already a Java lib that does it?
b) If not, would it be practical to write one using reflection?
In case of (b), any recomendations/guidelines/code skeletons would be appreciated.
The bean mapping library Dozer does an excellent job of this and is dead simple to use.
Simply map an instance of the bean returned by Hibernate to it's own class:
Person person = session.load(...);
BeanMapper mapper = ...;
Person cleanPerson = mapper.map(person, Person.class);
voila, no more Hibernate proxies or lazy-loaded collections!
The class org.apache.commons.beanutils.BeanUtilsBean probably does almost everything you want. The copyProperties method will go through calling the getters on your Entity and looking for setters with a matching property name on a target object you provide. You may need to handle some nested entities, depending on what kind of behavior you want and if/how you map relationships.
If you need to get more sophisticated you can register a Converter for turning your nested entity types into something else as well.
There is an interesting discussion about your problem here
http://www.mojavelinux.com/blog/archives/2006/06/hibernate_get_out_of_my_pojo/
Several solutions are proposed in the comments. In particular
http://code.google.com/p/entity-pruner/
http://www.anzaan.com/2010/06/serializing-cglib-enhanced-proxy-into-json-using-xstream/
I personally am huge on layer separation, and would argue that classes that you want to serialize across the wire or to XML should actually be separate from your data access layer classes, which would also solve the problem.
class SerializablePerson
{
... fields you care about ...
SerializablePerson(Person person)
{
... set only what you care about ...
}
}
You could have a Person class without persistence information wrapped by a persistent counterpart, like this:
public class Person implements Serializable
{
private String name;
// others.
}
public class PersistentPerson
{
private Long id;
private Person data; //
public Person getPerson() { return this.data; }
}
I'm not sure the design is worth it. The dual model makes me throw up in my mouth a little, just while writing this example.
The larger question is: Why do you think this is necessary? IF there's no good way to tell XStream to not include the id when serializing, I'd say it'd be better to write your own javax.xml.bind.Marshaller and javax.xml.bind.Unmarshaller to get what you want.
There are better ways to solve this problem than bastardizing your entire design.

Tagging Interfaces in Java

What are tagging interfaces and what are they used for?
A tagging interface typically has some magic associated with it: either directly built into the VM, or using reflection. Because the magic could technically apply to any class, you use the tagging to indicate that you thought well about the magic and whether it applies to your class.
Because sometimes, it really makes sense if some property of a type can be used as a type itself - Serializable comes to mind. If I make a method like this:
public void save(Object data){ ... }
... you don't really know how that data will be saved. VM serialization? Bean property serialization? Some homebrewed scheme? Whereas if you write it like this:
public void save(Serializable data){ ... }
... it is quite clear (if only the designer of ObjectOutputStream had used this possibility!). Sometimes it makes sense to use annotations when you want to add meta-data to types, but in this case, I'd argue for a tagging interface.
The question of marker interfaces vs annotations is discussed in Bloch's "Effective Java", and part of that section is available on google books here
It was used to mentioned some property of a class (like Serializable shows, that the class is allowed to serialize). Now annotations could do this job.
In addition to the other answers marker interfaces can also be used to specify additional properties of a class that is not inherited by some other already-implemented interface. One example of this would be the interface RandomAccess. It denotes a collection that can be accessed randomly without loss of performance and does not have to be accessed via an iterator to achieve that performance.
You can tag your class with a tagging interface to say to your fellow developer and consumer of your class that you explicitely support that functionality. Think of Serializable; someone who needs to persist a Session and uses serialization to do that can safely use an object of your class.
It can be further used in reflection; nowadays it is common to use annotations to do this but in the olden days you can inspect a class, check whether it implements a certain interface (like DAO) and if so, process the object further (I'm thinking about the Entity annotation here).
tagging interfaces are interfaces with no abstract methods inside , they are used to add a data type for the class which implements them and to be a parent interface for other interfaces ( especially with multiple inheritance in interfaces )
public interface name {}
public interface john1 {}
public interface john2 {}
public interface Demo extends john1 , john2 , name {}
** when JVM sees the name interface , it will find out that the Demo will exert a specific cenario .
I would also add you can use tagging interfaces to restrict ownership of an instance:
interface IFlumThing;
interface IFlooThing;
class BaseThing {...}
class FlumThing extends BaseThing implements IFlumThing {};
class FlooThing extends BaseThing implements IFlooThing {};
class Flum {
addThing(IFlumThing thing){...};
}
class Floo {
addThing(IFlooThing thing){...};
}

Categories