当前位置: 首页 > 知识库问答 >
问题:

用MySQL和Oracle实现Hibernate自动密钥生成

符允晨
2023-03-14

带注释的类中的followig代码可用于两个数据库的自动键生成,但如果主键是自设置的,则会失败。

@GeneratedValue(strategy=GenerationType.AUTO, generator="sequence_generator")
@SequenceGenerator(name="sequence_generator", sequenceName="SEQUENCE1")
@Column(name = "id", unique = true, nullable = false)
public Integer getId() {
    return this.id;
}

如果没有@GeneratedValue和@SequenceGenerator注释,则可以手动设置主键,但自动生成无法工作。

共有1个答案

邬朗
2023-03-14

即使使用了generationtype.auto而不使用任何特定于序列的参数,也无法保存分配的标识符。

如果你愿意做出一些妥协,有一些变通办法:

>

  • 一种方法是切换到分配的标识符。您可以使用UUID标识符,这对MySQL和Oracle都适用,您还可以手动分配值。

        public interface Identifiable<T extends Serializable> {
            T getId();
        }
    
        public class AssignedTableGenerator extends TableGenerator {
    
            @Override
            public Serializable generate(SessionImplementor session, Object obj) {
                if(obj instanceof Identifiable) {
                    Identifiable identifiable = (Identifiable) obj;
                    Serializable id = identifiable.getId();
                    if(id != null) {
                        return id;
                    }
                }
                return super.generate(session, obj);
            }
        }
    
        doInTransaction(session -> {
            for (int i = 0; i < 5; i++) {
                session.persist(new AssignTableSequenceIdentifier());
            }
            AssignTableSequenceIdentifier tableSequenceIdentifier = new AssignTableSequenceIdentifier();
            tableSequenceIdentifier.id = -1L;
            session.merge(tableSequenceIdentifier);
            session.flush();
        });
    

    生成以下语句:

        select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
        insert into sequence_table (sequence_name, next_val)  values (default,1)
        update sequence_table set next_val=2  where next_val=1 and sequence_name=default
        select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
        update sequence_table set next_val=3  where next_val=2 and sequence_name=default
        select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
        update sequence_table set next_val=4  where next_val=3 and sequence_name=default
        select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
        update sequence_table set next_val=5  where next_val=4 and sequence_name=default
        select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
        update sequence_table set next_val=6  where next_val=5 and sequence_name=default
        select identityvs0_.id as id1_0_0_ from assigneTableIdentifier identityvs0_ where identityvs0_.id=-1
        insert into assigneTableIdentifier (id) values (1, 2)
        insert into assigneTableIdentifier (id) values (2, 4)
        insert into assigneTableIdentifier (id) values (5, -1)
    

    对于Oracle,您可以将序列和分配的生成器组合在一起。简而言之,考虑到下面的生成器:

    public class AssignedSequenceStyleGenerator 
        extends SequenceStyleGenerator {
     
        @Override
        public Serializable generate(SessionImplementor session, 
            Object obj) {
            if(obj instanceof Identifiable) {
                Identifiable identifiable = (Identifiable) obj;
                Serializable id = identifiable.getId();
                if(id != null) {
                    return id;
                }
            }
            return super.generate(session, obj);
        }
    }
    

    您可以将其映射到您的实体,如下所示:

    @Id
    @GenericGenerator(
        name = "assigned-sequence",
        strategy = "com.vladmihalcea.book.hpjp.hibernate.identifier.AssignedSequenceStyleGenerator",
        parameters = @org.hibernate.annotations.Parameter(
            name = "sequence_name", 
            value = "post_sequence"
        )
    )
    @GeneratedValue(
        generator = "assigned-sequence", 
        strategy = GenerationType.SEQUENCE
    )
    private Long id;
    

  •  类似资料:
    • 问题内容: 我正在使用 Java 应用程序,该应用程序应该在具有相同数据库架构的两个不同数据库上执行CRUD操作(使用 Hibernate 4.3.8)。有一个 MySQL (版本5.1.73)和一个 Oracle (11g Express Edition版本11.2.0.2.0-64位)数据库。 使用Hibernate Code Generation从数据库表中生成带有 JPA批注的 Java类

    • 问题内容: 如何使用MyBatis获取插入的生成密钥?我阅读了许多有关此问题的页面,但仍然被屏蔽,请问有人可以帮助我吗?这是我的代码: 桌子: 道: mapper.java: mapper.xml 怎么了?如何获得此插入的生成的密钥?谢谢! 问题答案: 如果要获取生成的主键,则应通过或传递参数。 调用映射方法时,将值映射。

    • 我正在尝试创建一个公钥以允许我推送到Git,但我的. ssh文件夹尚未创建。 以下是我运行的命令: $ssh-keygen-t rsa-Cemaill@me.com 生成公共/私有rsa密钥对 输入保存密钥的文件(/h/.ssh/id\u rsa): 这就是H:驱动器配置、数据、配置文件、配置文件中的全部内容。V2 我认为有一个问题,因为当我得到提示输入文件,其中保存密钥(/h//. ssh/id

    • 我试图学习并在java中实现JWE来解决问题。我试图理解内容加密密钥是如何使用特定算法生成的(比如RSA-PKCS1\u 1.5)。 我知道如何使用密钥生成器生成一对密钥,然后使用公钥进行加密,使用私钥进行解密。此外,我知道如何通过给出声明来创建简单的JWT令牌,以及如何对其进行签名。我试着遵循以下步骤: 消息加密过程如下: 生成随机内容加密密钥(CEK)。CEK的长度必须至少等于所需加密密钥的长

    • 我正在使用Spring MVC Hibernate 在保存新记录时,会生成自动递增的新主键(db.MySQL)。我想获取并返回与上述方法相关的新的自动递增值。 更新我!

    • 在我的项目中,我们使用的是Oracle,我们也希望对MYSQL提供支持。在POJOS/Domains中,我们使用了序列生成器注释。Oracle有序列支持,但MYSQL没有。如何处理相同的代码库?有什么可以帮我的吗。 注意:我们不想使用标识注释@generatedvalue(strategy=generationtype.IDENTITY)更改现有代码