Java Hibernate的错误问题:查询列表时自动添加记录

Java Hibernate的错误问题:查询列表时自动添加记录,java,spring,hibernate,Java,Spring,Hibernate,我正在使用-hibernate4-spring3 我面临着一个我无法理解的问题:当我试图在Hibernate中检索对象列表时,数据库的另一个表中充满了行。我怀疑我设置的“级联”和“获取”属性有问题,但我真的不明白 让我解释一下这个问题 这里有4个实体: 拥有所有凭据的用户,如用户名,已启用,权限列表和类似内容 记录用户角色的权限 一个ProfiledUser,其中包含所有与配置文件数据,地址数据,以及检查列表,最后 包含一些数据和对用户的引用的检查 我试图建立以下模型 @SuppressWarn

我正在使用-hibernate4-spring3

我面临着一个我无法理解的问题:当我试图在Hibernate中检索对象列表时,数据库的另一个表中充满了行。我怀疑我设置的“级联”和“获取”属性有问题,但我真的不明白

让我解释一下这个问题

这里有4个实体:

  • 拥有所有凭据的用户,如
    用户名
    已启用
    权限列表
    和类似内容
  • 记录用户角色的权限
  • 一个ProfiledUser,其中包含所有与
    配置文件数据
    地址数据
    ,以及
    检查列表
    ,最后
  • 包含一些数据和对用户的引用的检查
  • 我试图建立以下模型

    @SuppressWarnings("unchecked")
    @Override
    public List<Checkup> loadPendingCheckups()
    {
        Session session = sessionFactory.getCurrentSession();
        Query query = session.createQuery("from " + objName + " where pending is true");
        List<Checkup> checkupList = query.list();
        if(checkupList.isEmpty())
            return null;
        else
            return checkupList;
    }
    

    以下是课程:User

    @Entity
    @Table(name="USERS")
    @Inheritance(strategy=InheritanceType.JOINED)
    public class User implements UserDetails, DomainObject {
    
        private static final long serialVersionUID = 1L;
        private long id;
        //other stuff here
        Set<Authority> authorities = new HashSet<Authority>();
    
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        @Column(name="id", unique=true, nullable=false)
        public long getId() {
            return id;
        }
    
        public void setId(long id) {
            this.id = id;
        }
    
        @ElementCollection(fetch=FetchType.EAGER)
        @JoinTable(name="AUTHORITIES", joinColumns=@JoinColumn(name="user_id"))
        public Set<Authority> getAuthorities() {
            return authorities;
        }
    
        public void setAuthorities(Set<Authority> authorities) {
            this.authorities = authorities;
        }   
    }
    
    @Entity
    @Table(name="PROFILED_USERS")
    public class ProfiledUser extends User{
    
        private static final long serialVersionUID = 1L;
        //other stuff here. Everything with CASCADE ALL
        private Collection<Checkup> checkupMap = new HashSet<Checkup>();
    
        public ProfiledUser() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
        public Collection<Checkup> getCheckupMap() {
            return checkupMap;
        }
    
        public void setCheckupMap(Collection<Checkup> checkupMap) {
            this.checkupMap = checkupMap;
        }
    }
    
    最后是权威

    @Embeddable
    public class Authority implements GrantedAuthority{
    
        private static final long serialVersionUID = 1L;
        private String authority;  //Spring Security demands them to start with "ROLE_"
    
        public Authority() {
            super();
        }
    
        @Column(name="authority")
        public String getAuthority() {
            return this.authority;
        }
    
        //the administer is the one allowed to change the users' role
        @RolesAllowed("ROLE_ADMIN")
        public void setAuthority(String authority) {
            if(!authority.startsWith("ROLE_"))
                authority= (new String("ROLE_")).concat(authority.toUpperCase());
            this.authority = authority.toUpperCase();
        }
    }
    
    现在问题来了。当我尝试检索挂起检查的列表时(挂起是检查的布尔属性),请执行以下操作

    @SuppressWarnings("unchecked")
    @Override
    public List<Checkup> loadPendingCheckups()
    {
        Session session = sessionFactory.getCurrentSession();
        Query query = session.createQuery("from " + objName + " where pending is true");
        List<Checkup> checkupList = query.list();
        if(checkupList.isEmpty())
            return null;
        else
            return checkupList;
    }
    
    生理学、测量学等都是体检中的内容。我想没关系,它被找回了。但在那之后,它会触发权限表中的大规模删除和插入

    编辑2: 将用户和权限之间的关系从
    @ElementCollection
    切换到
    @OneToMany
    似乎解决了问题。幸运的是,我正在设计数据库,这项修改是允许的。这个问题似乎消失了,但我仍然没有弄清楚ORM奇怪行为背后的原因。 更准确地说,最奇怪的是,当我要求从db Hibernate检索检查时,触发了大量的错误

  • 删除授权项目
  • 插入授权项目

  • 如果有人能指出这一点,我们将不胜感激。

    我不确定这是否是您的问题的原因,但您的
    ProfiledUser
    check
    之间的双向关系配置不正确

    双向一对多关系的配置如下:

    • 一面用
      @manytone
      注释,另一面用
      @OneToMany
    • @OneToMany
      必须具有指向相应的
      @ManyToOne
      属性的
      mappedBy
      属性
    • 物理映射注释(
      @JoinColumn
      )应位于
      @ManyToOne
    大概是这样的:

    public class ProfiledUser extends User{
        @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy = "profiledUser")
        public Collection<Checkup> getCheckupMap() {
            return checkupMap;
        }
        ...
    }
    
    public class Checkup implements DomainObject {
        @ManyToOne(fetch=FetchType.EAGER)
        @JoinColumn(name="profiledUser")
        public ProfiledUser getProfiledUser() {
            return profiledUser;
        }
        ...
    }
    
    公共类ProfiledUser扩展了用户{
    @OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER,mappedBy=“profiledUser”)
    公共集合getCheckupMap(){
    返回检查图;
    }
    ...
    }
    公共类检查实现DomainObject{
    @manytone(fetch=FetchType.EAGER)
    @JoinColumn(name=“profiledUser”)
    公共ProfiledUser getProfiledUser(){
    返回剖面仪;
    }
    ...
    }
    
    你赢得了我永远的感激!经过您的更正,代码似乎工作正常。实际上,我认为在庆祝活动之前多测试一下我的应用程序是明智的。顺便说一句,现在没有奇怪的db人口。一点想法:我知道在使用工具(hibernate)之前了解它是必要的,但有时文档太多,时间很短。在出现奇怪的配置(比如我的配置)的情况下,最好有hibernate的支持。非常感谢。不幸的是,问题又回来了。
    public class ProfiledUser extends User{
        @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy = "profiledUser")
        public Collection<Checkup> getCheckupMap() {
            return checkupMap;
        }
        ...
    }
    
    public class Checkup implements DomainObject {
        @ManyToOne(fetch=FetchType.EAGER)
        @JoinColumn(name="profiledUser")
        public ProfiledUser getProfiledUser() {
            return profiledUser;
        }
        ...
    }