为接口的@Embed覆盖@ManyToOne targetEntity

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为接口的@Embed覆盖@ManyToOne targetEntity相关的知识,希望对你有一定的参考价值。

我正在为ORM使用休眠和注释。我有所有bean的接口,并且正在使用targetEntity建立关系:休眠无法派生类型,因为getter返回一个接口而不是bean。

我获得了嵌入式bean的MappingException(无法确定类型)。

@Entity(name="FieldBean")
public class FieldBean implements Field 
    ...


@Embeddable
public class FacetBean implements Facet 
    ...    

    @ManyToOne(targetEntity = FieldBean.class)
    @JoinColumn(name = "field_id")
    public Field getField() 
        return field;
    



@Entity(name = "Chart")
public class ChartBean implements Chart 

    @Embedded
    @AssociationOverride(
        name = "field",
        joinColumns = @JoinColumn(name = "category_facet_field_id")
    )
    public Facet getCategoryFacet() 
        return categoryFacet;
    


我得到MappingException:无法确定以下字段的类型:表,图表的字段,列的[org.hibernate.mapping.Column(field)]

使用bean代替接口来进行属性和getter / setter声明可以解决此问题,但我想坚持使用接口。仅将bean用于属性声明并不能解决问题。

有人能指出我正确的方向吗?

答案

我已经对此使用了可行的解决方案一段时间了,但是其中包括一小部分供应商锁定的情况。我发现没有办法仅使用JPA注释来做到这一点,但是有一个Hibernate特定的注释@Target可以解决问题。我已经做了与您一样的事情,并取得了预期的结果。但是,我没有使用您的其他注释,所以我不能保证它会按您期望的那样工作。

Embeddable类中没有什么奇怪的事情:

public interface PointsInt extends Serializable 
    int offensivePoints();

    int defensivePoints();



@Embeddable
public class Points implements PointsInt 
    private int def;
    private int off;
    public int offensivePoints()  return off; 

    public int defensivePoints()  return def; 


但是在消费类中,我们使用了Hibernate的@Target

import javax.persistence.*;
import org.hibernate.annotations.Target;

@Entity
public class Series extends LongIdEntity implements Serializable 

    @Embedded
    @Target(Points.class)
    private PointsInt points;
    // I prefer to declare my annotations on fields rather than methods

结果:

mysql> describe series;
+-----------------+-------------+------+-----+---------+----------------+
| Field           | Type        | Null | Key | Default | Extra          |
+-----------------+-------------+------+-----+---------+----------------+
| id              | bigint(20)  | NO   | PRI | NULL    | auto_increment |
| def             | int(11)     | YES  |     | NULL    |                |
| off             | int(11)     | YES  |     | NULL    |                |
+-----------------+-------------+------+-----+---------+----------------+
3 rows in set (0.12 sec)
另一答案

我过去使用jpa告诉我不要使用继承。没有映射的超类,没有接口等……只是带有成员的实体。我与hibernate以及eclipselink一起工作,并且两者在继承方面都存在着非常非常的问题。用jpa编写一个支持多个提供程序的持久层非常困难,因为所有这些提供程序都有很多错误。保持尽可能简单。不要使用任何“特殊”功能。我向您保证,当尝试更改提供程序或仅在不同的应用程序服务器(如jboss(休眠)或glassfish / weblogic(eclipse /顶部链接))上运行软件时,如果拥有一个最简单的持久层且使用的资源很少,那么您会很高兴功能越好。我不知道这是否是错误,但我认为是。

另一答案

除了讨论接口是否被过度使用之外,问题的根源在于您正在使用需要使用类的接口。具体来说,您要在返回非JPA对象的方法上放置JPA批注。

解决方案非常简单:将注释放在字段上,而不是方法上。

@Embeddable
public class FacetBean implements Facet 

    @ManyToOne(targetEntity = FieldBean.class)
    @JoinColumn(name = "field_id")
    private FieldBean field;

    public Field getField() 
        return field;
    

唯一的缺点是,如果您坚持使用带有Field参数的设置方法,那么您将在任何设置方法上遇到问题。但是,如果您希望能够分配任何Field实例,即使它不是JPA托管的bean,也仍然会遇到此类问题。

以上是关于为接口的@Embed覆盖@ManyToOne targetEntity的主要内容,如果未能解决你的问题,请参考以下文章

JPA @ManyToOne 用于休眠

LA和TA

Hibernate @ManyToOne @JoinColumn 始终为空

Chromium插件(Plugin)执行3D渲染的过程分析

将一对 @ManyToOne 相关属性标记为唯一。可能的?

POD 安装问题:“`ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES”