java implement 泛型,如何用泛型关系实现多态的JPA实体

I'm trying to use JPA 2.0 to create polymorphic entities with generic relations. There should be two tables, an event table and a notification table. Inside those table are concrete entities that are related to one another, like so:

Event

| |

LoginEvent

Logically this should be possible in hibernate, as it is possible in SQL:

+----------+ +----------+

| Event | | Notif |

+----------+ +----------+

| | | Id |

| Id |

| Type |

| ... | | ... |

+----------+ +----------+

This is what I have:

@Entity

@Inheritance

public abstract class Event{

...

}

@Entity

public class LoginEvent extends Event{

...

}

@Entity

@Inheritance

public abstract class Notification{

@ManyToOne(optional=false, targetEntity=Event.class)

@JoinColumn

private X event;

...

}

@Entity

public class LoginNotification extends Notification{

...

}

Using this code, I can persist and fetch any Event, Notification, LoginEvent, or NotificationEvent, but it falls down when I try to use the LoginNotification_.event relation in my JPA 2.0 metamodel queries. This issue explains something similar.

public static volatile SingularAttribute event;

When I try to do a join in a criteria query, I get an error:

EntityManager em = getEntityManager();

CriteriaBuilder cb = em.getCriteriaBuilder();

CriteriaQuery query = cb.createQuery(LoginNotification.class);

Root root = query.from(LoginNotification.class);

// This line complains: Type mismatch: cannot convert from

// Join to Join

Join join =

root.join(LoginNotification_.event, JoinType.INNER);

I can get around this error, by adding a new SingularAttribute to the LoginNotification_ metamodel, but this fails in execution:

public abstract class LoginNotification_ extends Notification_ {

// Adding this Removes Type mismatch error, but causes run-time error

public static volatile SingularAttribute event;

...

}

According to some posts, generic relations won't work (How to handle JPA annotations for a pointer to a generic interface), but by using a @ManyToOne(optional=false, targetEntity=Event.class) annotation, we can get them to behave. Unfortunately, the generics seem to break the JPA criteria query.

Are there any suggestions on how I can perform this lookup? I can use LoginNotification.getEvent() in my code, but I cannot use LoginNotification_.event in my JPA metamodel joins. What's the alternative to using generics to accomplish this?

@Pascal Thivent - Can you answer this?

解决方案

One solution to this is to avoid using the 'join' function and do a full cross join instead:

EntityManager em = getEntityManager();

CriteriaBuilder cb = em.getCriteriaBuilder();

CriteriaQuery query = cb.createQuery(LoginNotification.class);

Root notfRoot = query.from(LoginNotification.class);

Root eventRoot = query.from(LoginEvent.class);

...

query.where(cb.equals(notfRoot.get(Notification_.event), eventRoot.get(Event_.id)), ...(other criteria));

I would assume that a decent query optimizer should make short work of this, but if anyone has any insight on the efficiency of this approach I would be keen to hear it!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值