JPA @MappedSuperclass与Hibernate在一个单独的jar中出现问题

时间:2014-06-27 14:45:34

标签: java hibernate jpa

我的问题来自于我正在尝试重用包含一些基本字段(如Long Id)的映射超类。 这个映射的超类看起来像这样:

@MappedSuperclass
public abstract class AbstractBaseEntity {

    protected Integer id;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "Id", nullable = false, unique = true, columnDefinition = "int")
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
}

它位于一个罐子里,这样每个人都可以轻松地重复使用它。 显然,所有工作都很完美,除非扩展它的实体实际上有它们之间的关系,并且您尝试使用基于这些关系的查询来获取数据。 例: 假设您有一个实体 Organization ,其中包含一个或多个 User

@Entity
@Table(name = "Organizations")
public class Organization extends AbstractBaseEntity {

    private Set<User> users;

    @OneToMany(mappedBy = "organization", fetch = FetchType.LAZY)
    public Set<User> getUsers() {
        return users;
    }

    public void setUsers(Set<User> users) {
        this.users = users;
    }
}

@Entity
@Table(name = "Users")
public class User extends AbstractBaseEntity {

    private Organization organization;

    @ManyToOne
    @JoinColumn(name = "Organization_ID", nullable = false)
    public Organization getOrganization() {
        return organization;
    }

    public void setOrganization(Organization organization) {
        this.organization = organization;
    }
}

现在问题在于:如果我使用 DETACHED 组织对象作为此类查询的参数:

SELECT u from User u where u.organization = ?1

然后Hibernate抛出以下异常:

 org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.example.Organization

这对我没有任何意义,它不应该为这种查询要求附加实体,因为它需要的只是它的id。

但是,如果我从jar中取出 AbstractBaseEntity 并将其放在与组织和用户相同的项目中,那么所有这些都与分离的组织和所有组织完美配合......

这看起来非常像我的错误。关于如何解决它的任何线索?

PS。我已经尝试将abstractBaseEntity显式指定为persistence.xml中的一个类,如此处所指定的那样 - JPA @MappedSuperclass in separate JAR in Eclipse(很奇怪,但值得一试)......没有工作

3 个答案:

答案 0 :(得分:0)

只是猜测,但实体需要实施Serializable。看看是否能解决您的问题。

答案 1 :(得分:0)

很抱歉地说,但我认为你根本不能&#34;拉&#34;来自不同编译单元的MappedSuperclass。这是因为JPA提供程序可能使用代码检测来访问实体字段。

您是否尝试在自己的工作区创建克隆类?

来自德国, 托马斯

答案 2 :(得分:0)

根据JPA规范,如果你在单独的jar中有jpa类,你应该将它添加到persistence.xml(我不知道,如果Hibernate要求,但你可以尝试一下)。尝试将以下条目添加到persistence.xml <jar-file>entity.jar</jar-file>

检查此post如何在jar文件标记中定义路径。