hibernate表关联出现的异常及解决方法

最近边学边用hibernate写东西,然后出现各种问题,总结一下出现的问题及解决方法

在存在@OneToMany、@ManyToOne的情况报Table ‘table.A_B’ doesn’t exist异常

异常出现的背景:

排除真正的表不存在的因素外,该异常通常出现的情况如下:

create table a
(
    id int primary key not null
 );
 create table b
(
    id int primary key not null,
    aID int not null,
    foreign key(aID) references a(id)
 )

就是这样两张简单的表,下面是对应的实体类:

@Entity
@Table(name="a")
public class A{
    @Id
    @Column
    private int id;
    @OneToMany(cascade = CascadeType.ALL,fetch=FetchType.EAGER)
    private Set<B> b;
    ...
}

@Entity
@Table(name="b")
public class B{
    @Id
    @Column
    private int id;
    @ManyToOne(cascade = CascadeType.ALL,fetch=FetchType.EAGER)
    private A a;
    ...
}

异常出现原因:

如果实体类这样写的话,操作时候基本都会报这个错,因为这时它认为是A、B类的关系是靠第三个表来维持,解决方法很简答:

解决方法:

@Entity
@Table(name="a")
public class A{
    @Id
    @Column
    private int id;
    //加上mappedBy用于指定B类中哪个属性作为外键来保存关系
    @OneToMany(cascade = CascadeType.ALL,mappedBy="a",fetch=FetchType.EAGER)
    private Set<B> b = new HashSet<B>();
    ...
}

@Entity
@Table(name="b")
public class B{
    @Id
    @Column
    private int id;
    @ManyToOne(cascade = CascadeType.ALL,fetch=FetchType.EAGER)
    //aID是数据库表中对应的列名
    @joinColumn(name="aID")
    private A a;
    ...
}

关键是joincolumn和mappedby这两个都不能漏

A different object with the same identifier value was already associated with the session

异常出现的背景:

信息是说session里面出现多个有一样identifier的对象,我出现这个错误时候是这样:

create table A
(
    id int primary key not null
);
create table B
(
    id int primary key not null,
    aid int not null,
    foreign key(aid) references A(id)
);
create table C
(
    id int primary key not null,
    pbid int not null,
    sbid int not null,
    foreign key(pbid) references B(id),
    foreign key(sbid) references B(id)
);

上面的表简单表述为:A有一个或者多个B,B和B之间存在父子(上下)关系,C表用于保存B的父子关系。
然后上面表对应的实体类如下:

@Entity
@Table(name="a")
public class A{
    @Id
    @Column
    private int id;
    @OneToMany(cascade=CascadeType.ALL,mappedBy="a",fetch=FetchType.EAGER)
    private Set<B> bs = new HashSet<B>();
    ...
}

@Entity
@Table(name="b")
public class B{
    @Id
    @Column
    private int id;
    @ManyToOne(cascade=CascadeType.ALL)
    @joinColumn(name="aid")
    private A a;
    @OneToMany(cascade=CascadeType.ALL,mappedBy="pb",fetch=FetchType.EAGER)
    private Set<C> cOfP = new HashSet<C>();
    @OneToMany(cascade=CascadeType.ALL,mappedBy="sb",fetch=FetchType.EAGER)
    private Set<C> cOfS = new HashSet<C>();
    ...
}

@Entity
@Table(name="c")
public class C{
    @Id
    @Column
    private int id;
    @ManyToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
    @joinColumn(name="pbid")
    private B pb;
    @ManyToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
    @joinColumn(name="sbid")
    private B sb;
    ...
}

下面为测试类,也就是如下面运行时,会出现该异常:

 //此处a已经存储进数据库,该表达式从库中获取a
 A a = aRpertory.get();
 //此处pb已经存储进数据库,该表达式从库中获取pb
 //而且pb.a的信息与上面的a完全一样:pb.a.getId() == a.getId()
 B pb = bRepertory。get();
 B sb = new B();
 sb.setA(a);
 C c = new C();
 c.setPb(pb);
 c.setSb(sb);
 //调用session保存c
 cRepertory.save(c);

异常出现原因:

结合异常的提示信息可以知道上面例子中出现异常的原因是:进行保存c的操作时,由于级联(cascade=CascadeType.ALL),会自动操作与c相关联的对象pb、sb,继续由于级联,会操作pb、sb相关联的a。
而pb是从数据库直接获取、sb是引用新创建的a对象,实际上pb.a和sb.a里面保存的信息是一样的,这就导致了pb.a和sb.a是不同的对象(different object),但是有同样的信息(with the same identifier value)

解决方法:

http://www.cnblogs.com/chenying99/archive/2012/05/10/2493630.html该博客介绍有3中方法。我这里就只介绍其中一种吧:
很简单就是在session操作之前,进行merge操作,如下:

    Transaction transaction  = session.getTransaction();
            transaction.begin();

    session.merge(object);

    session.save(object);
    transaction.commit();

P.S.这样写之后可能会引发另一个错误,就是下面这个错误

Multiple representations of the same entity […] are being merged. Detached:[…];Detached:[…]

异常出现的背景:

就上在解决上面的异常(添加了session.merge())后,出现了该异常

解决方法:

在配置文件上加上:

<property name="hibernate.event.merge.entity_copy_observer">allow</property>

Cannot use identity column key generation with mapping for

异常出现背景:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class A{
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
}

@Entity
@Table(name="b")
public class B extends A{

}

@Entity
@Table(name="c")
public class C extends A{

}

我本意是A类不映射为数据库表,B、C类继承A,并各自映射成表,而且主键均为数据库自动升成(auto_increment)

解决方法:

其实这个错误主要是父类A,定义上出现错误,如果不希望父类A映射成表,不应该用@Entity,而应该是@MappedSuperclass

@MappedSuperclass
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class A{
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当在 Hibernate 中执行查询时,出现 "could not extract ResultSet" 错误通常示查询执行过程中发生了问题,导致无法从数据库中提取结果集。 这个错误可能有多种原因,以下是一些常见的可能性和解决方法: 1. SQL 查询错误:请确保您的 HQL 或 SQL 查询语句是有效的,并且满足数据库中和列的存在和关联关系。检查查询语句中的名、列名、关联条件等是否正确。 2. 数据库连接问题:该错误也可能是由于数据库连接问题引起的。请确保您的数据库连接配置正确,并且数据库服务器可正常访问。检查数据库连接字符串、用户名、密码等配置是否正确。 3. 数据库事务问题:如果您在查询执行之前启动了一个事务,并且在查询执行期间发生了异常或错误,可能会导致 "could not extract ResultSet" 错误。请确保事务管理正确,包括事务的开始、提交和回滚。 4. 查询结果不匹配:如果您的查询结果与您指定的实体或返回型不匹配,也可能导致此错误。请检查查询结果与实体或返回型之间的匹配关系,并确保它们一致。 5. 数据库结构变化:如果在查询执行之前进行了数据库结构的更改(例如添加或删除列),但是 Hibernate 的实体或映射文件没有相应地更新,也可能导致此错误。请确保实体和数据库结构保持同步。 如果以上解决方法都不起作用,建议提供更具体的错误消息、查询语句和相关的代码,以便更好地帮助您解决问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值