Multiple #ManyToMany sets from one join table - java

I'm mapping a proprietary database to Hibernate for use with Spring. In it, there are a couple of jointables that, for entity A and entity B have the following schema:
CREATE TABLE AjoinB (
idA int not null,
idB int not null,
groupEnum enum ('groupC', 'groupD', 'groupE'),
primary key(idA, idB, groupEnum)
);
As you can see, this indicates that there can be multiple A-B relationships that put them in different groups. I'd like to end up with, first line for entity A and second for entity B, the following sets
Set<B> BforGroupC, BforGroupD, BforGroupE;
Set<A> AforGroupC, AforGroupD, AforGroupE;
So far, I've only managed to put them in one set and disregard the groupEnum relationship attribute:
#ManyToMany(targetEntity=B.class, cascade={ CascadeType.PERSIST, CascadeType.MERGE } )
#JoinTable(name="AjoinB", joinColumns=#JoinColumn(name="idA"), inverseJoinColumns=#JoinColumn(name="idB") )
private Set<B> BforAllGroups;
and
#ManyToMany( mappedBy = "BforAllGroups", targetEntity = A.class )
private Set<A> AforAllGroups;
How can I make multiple sets where they belong either in groupC, groupD or groupE?
Cheers
Nik

If you're considering doing this, don't. Tables are cheap nowadays what's with the economy and all, so just create one per association; it'll be so much easier.
If you're bound by a legacy database and you can't change the structure of that table I would
Consider skaffman's solution first (+1, btw). Depending on your target database you may be able to write a trigger for your views that would insert adequate "discriminator" value.
If the above isn't possible in your DB, another solution is to use custom SQL for CRUD operations for your collections. Keep in mind that this will NOT work (e.g. your "discriminator value" won't get applied) for complex HQL queries involving your association as part of condition. You can also mix / match this with above - e.g. use views and use custom SQL for insert / delete.
If both of the above fail, go with "association as a separate entity" as suggested by framer8. That's going to be rather ugly (since we're assuming here you can't change your tables) due to composite keys and all extraneous code. It may, in fact, be impossible if any of your associations allows duplicates.

To my knowledge, Hibernate cannot use such a "discriminator" column in the way that you want. Hibernate requires a join table for each of them.
Perhaps you might be able to define additional views on the table, showing each of the groupings?

I think the advise anytime you need to access a field in a link table is to make the link table an object and a hibernate entity in its own right. A would have a set of AtoB objects and AtoB would have a set of B objects. I have a simmilar situation where the link table has a user associated with the link.
select joinTable.b from A a
left join a.AtoB joinTable
where joinTable.group = 'C'
It's not as elegant as having an implicit join done by hibernate, but it does give you the control you need.

Related

Hibernate: bidirectionality vs. unidirectionality, depending on relationship

Reading a wiki page about Hibernate I elaborated some perplexing conclusions:
1) Bidirectionality is reccomended in one-to-many
2) Bidirectionality is optional in many-to-one
3) Bidirectionality is normally present in many-to-many
4) Unidirectionality is reccomended in one-to-one relationships,
using as owner class the one with the primary key of the
relation (not the foreign key).
Are these statements true? Do you have any example to explain why in some cases unidirectionality is reccomended and in others bidirectionality is reccomended instead?
Here's the wiki page (read under "concepts"):
http://wiki.elvanor.net/index.php/Hibernate
Note that "bidirectionality" in the context of Hibernate means that in your Java classes, both sides of the relationship maintain a link to the other side. It has no impact on the underlying database schema (except in the case of indexed collections, see below), it's just whether or not you want the Java side to reflect that.
For all of your conclusions, "recommended" actually translates to "it usually ends up making sense, given your business logic, that you'd do it this way".
You really want to read through chapters 7 and 8 of the Hibernate Core Reference Manual.
It's recommended if you need it. A lot of convenience comes from specifying a bidirectional relationship; particularly it becomes possible to navigate the relationship from both ends in your business logic. However, if you don't actually need to do this, there's nothing to gain. Use whatever is most appropriate for the situation. In practice I've found that I want to specify both ends of the relationship to Hibernate more often than not -- but it is not a rule, rather, it reflects what I want to accomplish.
This is true. In a many-to-one (or one-to-many) relationship, it is optional. Consider the following schema:
table: users
fields: userId, userName
table: forumPosts
fields: postId, userId, content
Where forumPosts.userId is a foreign key into users. Your DAO classes might be (getters/setters omitted for brevity):
public class User {
private long userId;
private String userName;
}
public class ForumPost {
private long postId;
private User user;
private String content;
}
As you can see, this is a unidirectional many-to-one relationship (ForumPost-to-User). The ForumPost links to the user, but the User does not contain a list of ForumPosts.
You could then add a one-to-many mapping to User to make it have a list of ForumPosts. If you use a non-indexed collection like a set, this has no impact on the database schema. Merely by specifying both sides to Hibernate, you have made it bidirectional (using exactly the same schema as above), e.g.:
public class User {
private long userId;
private String userName;
private Set<ForumPost> forumPosts;
}
public class ForumPost {
private long postId;
private User user;
private String content;
}
Hibernate will now populate User.forumPosts when necessary (essentially with SELECT * FROM forumPosts WHERE userId = ?). The only difference between bidirectional and unidirectional here is that in one case Hibernate fills a set of ForumPosts in User, and in the other case it doesn't. If you ever have to get a collection of any given user's posts, you will want to use a bidirectional relationship like this rather than explicitly constructing an HQL query. Depending on your inverse/insert/update/cascade options in your relationship, you can also add and remove posts by modifying the User's set of posts, which may be a more accurate reflection of your business logic (or not!).
The reason I specified that non-indexed collections don't impact the underlying schema is because if you want to use an ordered, indexed collection like a list, you do have to add an extra list index field to the forumPosts table (although you do not have to add it to the ForumPost DAO class).
This is true, but is not a requirement and it's deeper than that. Same as above. Bidirectionality is usually present in many-to-many. Many-to-many relationships are implemented with a third join table. You specify the details of this table on both sides of the relationship. You can simply not specify the relationship on one side, and now it's a unidirectional relationship. Again, whether or not you tell Hibernate about the mapping is what determines if its unidirectional or bidirectional (in the context of Hibernate). In this case it also has no impact on the underlying schema unless you are using an ordered index collection. In fact, the many-to-many example in the Hibernate reference manual is a unidirectional setup.
In reality, it would be odd to have a unidirectional many-to-many relationship, unless perhaps you are working with an existing database schema and your particular application's business logic has no need for one of the sides of the relationship. Usually, though, when you've decided you need a many-to-many relationship, you've decided that because you need to maintain a collection of references on both sides of the relationship, and your DAO classes would reflect that need.
So the correct conclusion here is not merely that "bidirectionality is normally present in many-to-many", but instead "if you've designed a database with a join table, but your business logic only uses a unidirectional relationship, you should question whether or not your schema is appropriate for your application (and it very well may be)".
This is not true. Exactly the same as all the points above. If you need to navigate the one-to-one relationship from both sides, then you'd want to make it bidirectional (specify both sides of the mapping to Hibernate). If not, then you make it unidirectional (don't specify both sides of the mapping to Hibernate). This again comes down to what makes sense in your business layer.
I hope that helps. I left a lot of intricacies out. You really should read through the Hibernate documentation - it is not organized particularly well but Chapter 7 and 8 will tell you everything you need to know about collection mapping.
When I'm designing an application and a database from scratch, personally, I try to forget about Hibernate and the database entirely. I set up my DAOs in a way that makes sense for my business requirements, design a database schema to match, then set up the Hibernate mappings, making any final tweaks to the schema (e.g. adding index fields for ordered collections) at that point if necessary.

Need a setter on a JPA/Hibernate entity for an ID AND a foreign entity

I have two entities with a many-to-one relationship between them. Many B entities are related to an A entity. My B table has an A_ID column. In some situations, we may have a B entity that has an A_ID but doesn't relate to any row in A. I know this isn't ideal but it's part of the old system and we can't really touch this portion of the code.
With proper Hibernate entities, I'm able to add B entities when we have an A entity to associate with using B's setA() method and B's getAs().add() method. I don't see any way to deal with the case where I'd like to add a B entity that isn't associated with an A entity (B's A_ID = 10, for example, where there's no A with an ID = 10). Is this possible or am I stuck breaking our entity hierarchy at this point and dealing with it manually?
Is there some way to add a setAId() to the B entity and either use that or the setA() method but not both? Will Hibernate allow this? When I try to add the getter and setter on B, I get the following error:
MyHibernateException: Hibernate SessionFactory creation failed, hibernateCfgFileNm=hibernate.xml
...
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: test.B column: A_ID (should be mapped with insert="false" update="false")
Sorry for not providing code. I think this explanation is sufficient but if code is required, I can add it.
With my understanding of entity relations (I assume you're mapping these with standard JPA #ManyToOne / #OneToMany relations?) I believe you're going to run into some fun issues here.
I would create my A entities using a sequence generated ID, and allow for 'placeholder' A entities which do nothing but carry the A_ID from the old system. Just make your code aware that not every A entity will be a full entity (it may just place-hold those A_IDs you mentioned above) and gracefully handle it, allowing you to always provide an A entity, with an ID decoupled from the legacy system.
I don't think you'll be able to map the relation to the same column and set a value in the column without the relation causing issues -- unless perhaps if you mark the relation as LAZY fetch and catch the exceptions which are bound to occur when it tries to resolve the non-existent Entity A. That may also work -- in that case, try to map the relationship column as read-only (insert="false" update="false"), and do everything with the setAId(id). You may need to have your setA(A) method only operate on IDs rather than managed collections, since reading a collection will by it's very nature fetch any related rows.
Your best bet is to decouple from the IDs of the legacy system if the semantics of the legacy IDs loosely translate to 'here, this ID may be a null object.'

Recursive JPA query?

Does JPA 2 have any mechanism for running recursive queries?
Here's my situation: I have an entity E, which contains an integer field x. It also may have children of type E, mapped via #OneToMany. What I'd like to do is find an E by primary key, and get its value of x, along with the x values of all its descendants. Is there any way to do this in a single query?
I'm using Hibernate 3.5.3, but I'd prefer not to have any explicit dependencies on Hibernate APIs.
EDIT: According to this item, Hibernate does not have this feature, or at least it didn't in March. So it seems unlikely that JPA would have it, but I'd like to make sure.
Using the simple Adjacency Model where each row contains a reference to its parents which will refer to another row in same table doesn't co-operate well with JPA. This is because JPA doesn't have support for generating queries using the Oracle CONNECT BY clause or the SQL standard WITH statement. Without either of those 2 clauses its not really possible to make the Adjacency Model useful.
However, there are a couple of other approaches to modelling this problem that can applied to this problem. The first is the Materialised Path Model. This is where the full path to the node is flattened into a single column. The table definition is extended like so:
CREATE TABLE node (id INTEGER,
path VARCHAR,
parent_id INTEGER REFERENCES node(id));
To insert a tree of nodes looks some thing like:
INSERT INTO node VALUES (1, '1', NULL); -- Root Node
INSERT INTO node VALUES (2, '1.2', 1); -- 1st Child of '1'
INSERT INTO node VALUES (3, '1.3', 1); -- 2nd Child of '1'
INSERT INTO node VALUES (4, '1.3.4', 3); -- Child of '3'
So to get Node '1' and all of its children the query is:
SELECT * FROM node WHERE id = 1 OR path LIKE '1.%';
To map this to JPA just make the 'path' column an attribute of your persistent object. You will however have to do the book-keeping to keep the 'path' field up to date. JPA/Hibernate won't do this for you. E.g. if you move the node to a different parent you will have to update both the parent reference and determine the new path value from the new parent object.
The other approach is called the Nested Set Model, which is bit more complex. Probably best described by its originator (rather than added verbatim by me).
There is a third approach called Nested Interval Model, however this has a heavy reliance of stored procedures to implement.
A much more complete explanation to this problem is described in chapter 7 of The Art of SQL.
The best answer in this post seems like a massive work-around hack to me. I've already had to deal with data models where brilliant engineers decided it would be a good Idea to code Tree Hiarchies in DB fields as text such as: "Europe|Uk|Shop1|John" and with massive volumes of data in these tables. Not surprsingly, the performance of query of the form MyHackedTreeField LIKE 'parentHierharchy%' where killers.
Addressing this type of problem ultimately required creating In memory cache of the tree hiearchies and so many others...
If you need to run a recursive query and your data volume is not massive... make your life simple and simply load the DB fields you need to run your plan. And code your recursion in java.
Don't make it in the DB unless you have a good reason to do it.
And even if the volume of data you have is massive, you most likely can subdivide your problem into indepent recursive tree batches and process those one at time without needing to load all the data at once.
I know this question is old, but as it was linked in a different question, I wanted to give an update on this, as Blaze-Persistence offers support for working with recursive CTEs on top of the JPA model.
Blaze-Persistence is a query builder on top of JPA which supports many of the advanced DBMS features on top of the JPA model. To model CTEs or recursive CTEs, which is what you need here, you first need to introduce a CTE entity that models the result type of the CTE.
#CTE
#Entity
public class GroupCTE {
#Id Integer id;
}
A query that fetches a hierarchy of groups could look like the following
List<Group> groups = criteriaBuilderFactory.create(entityManager, Group.class)
.withRecursive(GroupCTE.class)
.from(Group.class, "g1")
.bind("id").select("g1.id")
.where("g1.parent").isNull()
.unionAll()
.from(Group.class, "g2")
.innerJoinOn(GroupCTE.class, "cte")
.on("cte.id").eq("g2.parent.id")
.end()
.bind("id").select("g2.id")
.end()
.from(Group.class, "g")
.fetch("groups")
.where("g.id").in()
.from(GroupCTE.class, "c")
.select("c.id")
.end()
.getResultList();
This renders to SQL looking like the following
WITH RECURSIVE GroupCTE(id) AS (
SELECT g1.id
FROM Group g1
WHERE g1.parent_group_id IS NULL
UNION ALL
SELECT g2.id
FROM Group g2
INNER JOIN GroupCTE cte ON g2.parent_group_id = cte.id
)
SELECT *
FROM Group g
LEFT JOIN Group gsub ON gsub.parent_group_id = g.id
WHERE g.id IN (
SELECT c.id
FROM GroupCTE c
)
You can find out more about recursive CTEs in the documentation: https://persistence.blazebit.com/documentation/core/manual/en_US/index.html#recursive-ctes
I had problem like this, querying a menu nodes from one table,
The way I founded was this:
suppose we have a class named Node,created a Unidirectional One-to-Many Association like this:
#OneToMany( fetch = FetchType.EAGER)
#JoinColumn(name = "parent_id", referencedColumnName = "id")
private List<Node> subNodeList;
also have a filed named for example boolean isRoot in entity, to mention if this node is root menu item ,
and then, by querying for nodes that there isRoot is true, we just get top nodes and because of FetchType.EAGER, we also get sub nodes in List.
This will cause multiple queries , but for small menu like things it will be ok.

OneToOne relationship with shared primary key generates n+1 selects; any workaround?

Imagine 2 tables in a relational database, e.g. Person and Billing. There is a (non-mandatory) OneToOne association defined between these entities, and they share the Person primary key (i.e. PERSON_ID is defined in both Person and Billing, and it is a foreign key in the latter).
When doing a select on Person via a named query such as:
from Person p where p.id = :id
Hibernate/JPA generates two select queries, one on the Person table and another on the Billing table.
The example above is very simple and would not cause any performance issues, given the query returns only one result. Now, imagine that Person has n OneToOne relationships (all non-mandatory) with other entities (all sharing the Person primary key).
Correct me if I'm wrong, but running a select query on Person, returning r rows, would result in (n+1)*r selects being generated by Hibernate, even if the associations are lazy.
Is there a workaround for this potential performance disaster (other than not using a shared primary key at all)? Thank you for all your ideas.
Imagine 2 tables in a relational database, e.g. Person and Billing. There is a (non-mandatory) OneToOne association defined between these entities,
Lazy fetching is conceptually not possible for non-mandatory OneToOne by default, Hibernate has to hit the database to know if the association is null or not. More details from this old wiki page:
Some explanations on lazy loading (one-to-one)
[...]
Now consider our class B has
one-to-one association to C
class B {
private C cee;
public C getCee() {
return cee;
}
public void setCee(C cee) {
this.cee = cee;
}
}
class C {
// Not important really
}
Right after loading B, you may call
getCee() to obtain C. But look,
getCee() is a method of YOUR class
and Hibernate has no control over it.
Hibernate does not know when someone
is going to call getCee(). That
means Hibernate must put an
appropriate value into "cee"
property at the moment it loads B from
database. If proxy is enabled for
C, Hibernate can put a C-proxy
object which is not loaded yet, but
will be loaded when someone uses it.
This gives lazy loading for
one-to-one.
But now imagine your B object may or
may not have associated C
(constrained="false"). What should
getCee() return when specific B
does not have C? Null. But remember,
Hibernate must set correct value of
"cee" at the moment it set B
(because it does no know when someone
will call getCee()). Proxy does not
help here because proxy itself in
already non-null object.
So the resume: if your B->C mapping
is mandatory (constrained=true),
Hibernate will use proxy for C
resulting in lazy initialization. But
if you allow B without C, Hibernate
just HAS TO check presence of C at the
moment it loads B. But a SELECT to
check presence is just inefficient
because the same SELECT may not just
check presence, but load entire
object. So lazy loading goes away.
So, not possible... by default.
Is there a workaround for this potential performance disaster (other than not using a shared primary key at all)? Thank you for all your ideas.
The problem is not the shared primary key, with or without shared primary key, you'll get it, the problem is the nullable OneToOne.
First option: use bytecode instrumentation (see references to the documentation below) and no-proxy fetching:
#OneToOne( fetch = FetchType.LAZY )
#org.hibernate.annotations.LazyToOne(org.hibernate.annotations.LazyToOneOption.NO_PROXY)
Second option: Use a fake ManyToOne(fetch=FetchType.LAZY). That's probably the most simple solution (and to my knowledge, the recommended one). But I didn't test this with a shared PK though.
Third option: Eager load the Billing using a join fetch.
Related question
Making a OneToOne-relation lazy
References
Hibernate Reference Guide
19.1.3. Single-ended association proxies
19.1.7. Using lazy property fetching
Old Hibernate FAQ
How do I set up a 1-to-1 relationship as lazy?
Hibernate Wiki
Some explanations on lazy loading (one-to-one)
This is a common performance issue with Hibernate (just search for "Hibernate n+1"). There are three options to avoiding n+1 queries:
Batch size
Subselect
Do a LEFT JOIN in your query
These are covered in the Hibernate FAQs here and here
Stay away from hibernate's OneToOne mapping
It is very broken and dangerous. You are one minor bug away from a database corruption problem.
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2128
You could try "blind-guess optimization", which is good for "n+1 select problems".
Annotate you field (or getter) like this:
#org.hibernate.annotations.BatchSize(size = 10)
java.util.Set<Billing> bills = new HashSet<Billing>();
That "n+1" problem will only occur if you specify the relationship as as lazy or you explicitly indicate that you want hibernate to run a separate query.
Hibernate can fetch the relationship to Billing with an outer join on the select of Person, obviating the n+1 problem altogether. I think it is the fetch="XXX" indication in your hbm files.
Check out A Short Primer On Fetching Strategies
use optional =true with a one-to-one relationship like this to avoid the n+1 issue
#OneToOne(fetch = FetchType.LAZY, optional=true)
#PrimaryKeyJoinColumn

Extending JPA entity data at runtime

I need to allow client users to extend the data contained by a JPA entity at runtime. In other words I need to add a virtual column to the entity table at runtime. This virtual column will only be applicable to certain data rows and there could possibly be quite a few of these virtual columns. As such I don't want to create an actual additional column in the database, but rather I want to make use of additional entities that represent these virtual columns.
As an example, consider the following situation. I have a Company entity which has a field labelled Owner, which contains a reference to the Owner of the Company. At runtime a client user decides that all Companies that belong to a specific Owner should have the extra field labelled ContactDetails.
My preliminary design uses two additional entities to accomplish this. The first basically represents the virtual column and contains information such as the field name and type of value expected. The other represents the actual data and connects an entity row to a virtual column. For example, the first entity might contain the data "ContactDetails" while the second entity contains say "555-5555."
Is this the right way to go about doing this? Is there a better alternative? Also, what would be the easiest way to automatically load this data when the original entity is loaded? I want my DAO call to return the entity together with its extensions.
EDIT: I changed the example from a field labelled Type which could be a Partner or a Customer to the present version as it was confusing.
Perhaps a simpler alternative could be to add a CLOB column to each Company and store the extensions as an XML. There is a different set of tradeoffs here compared to your solution but as long as the extra data doesn't need to be SQL accessible (no indexes, fkeys and so on) it will probably be simple than what you do now.
It also means that if you have some fancy logic regarding the extra data you would need to implement it differently. For example if you need a list of all possible extension types you would have to maintain it separately. Or if you need searching capabilities (find customer by phone number) you will require lucene or similar solution.
I can elaborate more if you are interested.
EDIT:
To enable searching you would want something like lucene which is a great engine for doing free text search on arbitrary data. There is also hibernate-search which integrates lucene directly with hibernate using annotations and such - I haven't used it but I heard good things about it.
For fetching/writing/accessing data you are basically dealing with XML so any XML technique should apply. The best approach really depends on the actual content and how it is going to be used. I would suggest looking into XPath for data access, and maybe look into defining your own hibernate usertype so that all the access is encapsulated into a class and not just plain String.
I've run into more problems than I hoped I would and as such I decided to dumb down the requirements for my first iteration. I'm currently trying to allow such Extensions only on the entire Company entity, in other words, I'm dropping the whole Owner requirement. So the problem could be rephrased as "How can I add virtual columns (entries in another entity that act like an additional column) to an entity at runtime?"
My current implementation is as follow (irrelevant parts filtered out):
#Entity
class Company {
// The set of Extension definitions, for example "Location"
#Transient
public Set<Extension> getExtensions { .. }
// The actual entry, for example "Atlanta"
#OneToMany(fetch = FetchType.EAGER)
#JoinColumn(name = "companyId")
public Set<ExtensionEntry> getExtensionEntries { .. }
}
#Entity
class Extension {
public String getLabel() { .. }
public ValueType getValueType() { .. } // String, Boolean, Date, etc.
}
#Entity
class ExtensionEntry {
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "extensionId")
public Extension getExtension() { .. }
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "companyId", insertable = false, updatable = false)
public Company getCompany() { .. }
public String getValueAsString() { .. }
}
The implementation as is allows me to load a Company entity and Hibernate will ensure that all its ExtensionEntries are also loaded and that I can access the Extensions corresponding to those ExtensionEntries. In other words, if I wanted to, for example, display this additional information on a web page, I could access all of the required information as follow:
Company company = findCompany();
for (ExtensionEntry extensionEntry : company.getExtensionEntries()) {
String label = extensionEntry.getExtension().getLabel();
String value = extensionEntry.getValueAsString();
}
There are a number of problems with this, however. Firstly, when using FetchType.EAGER with an #OneToMany, Hibernate uses an outer join and as such will return duplicate Companies (one for each ExtensionEntry). This can be solved by using Criteria.DISTINCT_ROOT_ENTITY, but that in turn will cause errors in my pagination and as such is an unacceptable answer. The alternative is to change the FetchType to LAZY, but that means that I will always "manually" have to load ExtensionEntries. As far as I understand, if, for example, I loaded a List of 100 Companies, I'd have to loop over and query each of those, generating a 100 SQL statements which isn't acceptable performance-wise.
The other problem which I have is that ideally I'd like to load all the Extensions whenever a Company is loaded. With that I mean that I'd like that #Transient getter named getExtensions() to return all the Extensions for any Company. The problem here is that there is no foreign key relation between Company and Extension, as Extension isn't applicable to any single Company instance, but rather to all of them. Currently I can get past that with code like I present below, but this will not work when accessing referenced entities (if for example I have an entity Employee which has a reference to Company, the Company which I retrieve through employee.getCompany() won't have the Extensions loaded):
List<Company> companies = findAllCompanies();
List<Extension> extensions = findAllExtensions();
for (Company company : companies) {
// Extensions are the same for all Companies, but I need them client side
company.setExtensions(extensions);
}
So that's were I'm at currently, and I have no idea how to proceed in order to get past these problems. I'm thinking that my entire design might be flawed, but I'm unsure of how else to try and approach it.
Any and all ideas and suggestions are welcome!
The example with Company, Partner, and Customer is actually good application for polymorphism which is supported by means of inheritance with JPA: you will have one the following 3 strategies to choose from: single table, table per class, and joined. Your description sounds more like joined strategy but not necessarily.
You may also consider just one-to-one( or zero) relationship instead. Then you will need to have such relationship for each value of your virtual column since its values represent different entities. Hence, you'll have a relationship with Partner entity and another relationship with Customer entity and either, both or none can be null.
Use pattern decorator and hide your entity inside decoratorClass bye
Using EAV pattern is IMHO bad choice, because of performance problems and problems with reporting (many joins). Digging for solution I've found something else here: http://www.infoq.com/articles/hibernate-custom-fields

Categories