当前位置: 首页 > 面试题库 >

MySQL上的@GeneratedValue多态抽象超类

澹台华采
2023-03-14
问题内容

在使用Hibernate和MySQL的Spring
MVC应用程序中,我有一个抽象超类BaseEntity,该超类管理模型中所有其他实体的ID值。该id字段使用@GeneratedValue。每当我的代码尝试保存任何扩展的子类时,我都会遇到问题BaseEntity。这个问题带有的选择GenerationType@GeneratedValue

在我的代码中BaseEntity试图将子类保存到底层MySQL数据库的每个位置,都会出现以下错误:

ERROR SqlExceptionHelper - Table 'docbd.hibernate_sequences' doesn't exist

我已经在SO和google上阅读了很多关于此的文章,但是它们要么处理其他数据库(不是MySQL),要么不处理抽象超类。我无法通过使用来解决问题,GenerationType.IDENTITY因为我正在使用抽象超类来管理id模型中所有实体的字段。同样,我无法使用,GenerationType.SEQUENCE因为MySQL不支持序列。

那么我该如何解决这个问题呢?

这是以下代码BaseEntity.java

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    protected Integer id;

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

    public boolean isNew() {return (this.id == null);}

}

这是扩展的其中一个实体的代码示例BaseEntity

@Entity
@Table(name = "ccd")
public class CCD extends BaseEntity{
    //other stuff
}

这是DDL:

CREATE TABLE IF NOT EXISTS ccd(
  id int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  #other stuff
)engine=InnoDB;SHOW WARNINGS;

这是DAO中的JPQL代码:

    @Override
    @Transactional
    public void saveCCD(CCD ccd) {
    if (ccd.getId() == null) {
        System.out.println("[[[[[[[[[[[[ about to persist CCD ]]]]]]]]]]]]]]]]]]]]");
        this.em.persist(ccd);
        this.em.flush();
    }
    else {
        System.out.println("]]]]]]]]]]]]]]]]]] about to merge CCD [[[[[[[[[[[[[[[[[[[[[");
        this.em.merge(ccd);
        this.em.flush();
    }
}

编辑:

@MappedSuperClass在这种情况下无法使用的原因是,我需要具有ManyToOne允许多个子类型可互换使用的关系。以AccessLog下面的类为例。它有一个actor_entity和一个target_entity。可以有多种类型的参与者实体和多种类型的目标实体,但是它们都继承自BaseEntity。这种继承使accesslogsMySQL中的基础数据表仅具有一个actor_entity_id字段和一个target_entity_id字段,而不必为每个字段具有多个字段。当我改变@Entity上面BaseEntity@MappedSuperClass,不同的错误被抛出,表明AccessLog无法找到BaseEntity
BaseEntity需要@Entity注解AccessLog以具有多态性。

@Entity
@Table(name = "accesslogs")
public class AccessLog extends BaseEntity{

    @ManyToOne
    @JoinColumn(name = "actorentity_id")
    private BaseEntity actor_entity;

    @ManyToOne
    @JoinColumn(name = "targetentity_id")
    private BaseEntity target_entity;

    @Column(name="action_code")
    private String action;
    //getters, setters, & other stuff
}

第二编辑:

根据JBNizet的建议,我创建了一个hibernate_sequences表,如下所示:

CREATE TABLE IF NOT EXISTS hibernate_sequences(
  sequence_next_hi_value int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
)engine=InnoDB;SHOW WARNINGS;

但是现在我收到以下错误:

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'sequence_name' in 'where clause'

这是导致错误的hibernatesql,然后是堆栈跟踪的后两行:

Hibernate: select sequence_next_hi_value from hibernate_sequences where sequence_name = 'BaseEntity' for update
ERROR MultipleHiLoPerTableGenerator - HHH000351: Could not read or init a hi value
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'sequence_name' in 'where clause'

我该如何解决?


问题答案:

因为您使用TABLE标识符生成器,​​所以需要创建该表。如果不使用增强型标识符生成器,则可能会使用MultipleHiLoPerTableGenerator。

MultipleHiLoPerTableGenerator可以将一个表用于所有表标识符生成器。

我的建议是从集成测试中获取表ddl,以防您使用hbmddl构建测试架构。如果使用flyway或liquibase进行测试,则可以添加一个maven插件来生成ddl模式。

一旦有了模式,就需要使用精确的create table命令并将其添加到MySQL数据库中。



 类似资料:
  • 我有一个子类,它声明了我的抽象超类中的所有方法,但它仍然给我一个错误,说明我的类不是抽象的。我不知道为什么会抛出这个错误。 我得到的具体错误是 PhoneBookEntry.java: 1:错误:PhoneBookEntry不是抽象的,并且不会覆盖可比中的抽象方法compareTo(Object) 我的问题代码: 还有我的子类:

  • 我正努力做到以下几点: 这里的关键点是关于制造新动物的台词。

  • 我得到了一个抽象类: 和两个自动生成的子类: 以及一个用于创建网络模式(请求/回复)的应用编程接口,该模式使用请求类型和回复类型(A和B预计将像上述那样是自动生成的FOPACImpl子类): 我从XML存根中提取主题字符串,以及两种类型A和B的字符串名称: 显然,Java中的反射不能直接处理“公共抽象”超类? 结果 1) 为什么“使用“受保护”的修饰符”?FooPACImpl。getClass()

  • 问题内容: 我有一个包含带有抽象超类的JAXB注释类的程序包。我想在Web服务接口中使用此超类,因此可以将任何子类作为参数传递。当我这样做时,会引发异常: 可以手动将marshall / unmarshall&参数作为字符串传递,但我想避免这种情况。有什么想法怎么做? 问题答案: 您是否在Web服务请求中指定了具体的实现?这对我来说很好: 抽象基类: 实现类: Web服务方法: 请求:

  • 问题内容: 我的数据模型代表法人实体,例如企业或个人。两者都是纳税实体,都具有TaxID,电话号码和邮件地址的集合。 我有一个Java模型,其中有两个扩展抽象类的具体类。抽象类具有两个具体类共有的属性和集合。 我正在 MySQL* 数据库上使用 Hibernate JPA注释,其类如下: * 问题是,和对象需要参考他们的主人,这是一个。hibernate抱怨: 看来这将是一个相当普遍的Java继承

  • 本文向大家介绍Python面向对象之接口、抽象类与多态详解,包括了Python面向对象之接口、抽象类与多态详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Python面向对象之接口、抽象类与多态。分享给大家供大家参考,具体如下: 接口类 继承有两种用途: 一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中