【问题标题】:How to prevent duplicate records in Mysql using annotations when using Hibernate使用Hibernate时如何使用注解防止Mysql中的重复记录
【发布时间】:2021-10-21 09:57:10
【问题描述】:

这是我在Java Hibernate 的第二天。我正在学习这个 YouTube 教程:

Hibernate Tutorial | Configuration File

我正在仔细跟踪每一步。我的问题是我可以多次推送相同的记录:

mysql> select * from Alien;
+------+-------+--------+
| aid  | aname | acolor |
+------+-------+--------+
|  101 | Navin | Green  |
|  101 | Navin | Green  |
|  101 | Navin | Green  |
|  101 | Navin | Green  |
|  101 | Navin | Green  |
|  101 | Navin | Green  |
|  101 | Navin | Green  |
+------+-------+--------+
7 rows in set (0.00 sec)

这是我的文件。

hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="hibernate.connection.password">cosmonauts</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/testdb</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.hbm2ddl.auto">
            update
        </property>
        <property name="show_sql=true"></property>
    </session-factory>
</hibernate-configuration>

Alien.java

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Alien {  // POJO
    
    @Id
    private int aid;
    private String aname;
    private String acolor;
    
    ... //getters and setters
}

App.java // 主类

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;

public class App {

    public static void main(String[] args) {
        Alien telusko = new Alien();
        telusko.setAid(101);
        telusko.setAname("Navin");
        telusko.setAcolor("Green");
        
        Configuration configuration = new Configuration().configure().addAnnotatedClass(Alien.class);
        
        StandardServiceRegistry reg = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
        SessionFactory sf = configuration.buildSessionFactory(reg);
        
        Session session = sf.openSession();
        
        Transaction tx = session.beginTransaction();
        session.save(telusko);
        tx.commit();
    }
}

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.student.sample</groupId>
  <artifactId>StudentSystem</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.26</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.5.6.Final</version>
    </dependency>
</dependencies>
</project>

我是不是误会了什么。请纠正我的错误。

在控制台上我得到了这个:

Aug 19, 2021 10:43:44 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate ORM core version 5.5.6.Final
Aug 19, 2021 10:43:45 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
Aug 19, 2021 10:43:45 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)
Aug 19, 2021 10:43:45 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001005: using driver [com.mysql.cj.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/testdb]
Aug 19, 2021 10:43:45 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001001: Connection properties: {password=****, user=root}
Aug 19, 2021 10:43:45 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001003: Autocommit mode: false
Aug 19, 2021 10:43:45 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections <init>
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
Aug 19, 2021 10:43:45 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
Aug 19, 2021 10:43:45 PM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@27e7c77f] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Aug 19, 2021 10:43:45 PM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]

请加入。

【问题讨论】:

    标签: java eclipse hibernate annotations


    【解决方案1】:

    Hibernate 5.5.6.Final 的正确休眠属性是hibernate.hbm2ddl.auto。请参阅休眠文档here。所以,请尝试替换您的hibernate.cfg.xml

    <property name="hbm2ddl.auto">update</property>
    

    <property name="hibernate.hbm2ddl.auto">update</property>
    

    生成的 DDL 脚本应该确保没有重复。如果属性不正确,Hibernate 将无法为您更新 DDL。

    更新

    我尝试过,应用程序按预期工作,并且正在生成主键约束。以下是生成的日志-

    Hibernate: create table Alien (aid integer not null, acolor varchar(255), aname varchar(255), primary key (aid)) engine=MyISAM
    Hibernate: insert into Alien (acolor, aname, aid) values (?, ?, ?)
    Aug 21, 2021 4:36:13 PM org.hibernate.Version logVersion
    INFO: HHH000412: Hibernate ORM core version 5.5.6.Final
    Aug 21, 2021 4:36:13 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
    INFO: HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
    Aug 21, 2021 4:36:13 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
    WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)
    Aug 21, 2021 4:36:13 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
    INFO: HHH10001005: using driver [com.mysql.cj.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/testdb]
    Aug 21, 2021 4:36:13 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
    INFO: HHH10001001: Connection properties: {password=****, user=root}
    Aug 21, 2021 4:36:13 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
    INFO: HHH10001003: Autocommit mode: false
    Aug 21, 2021 4:36:13 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections <init>
    INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
    Sat Aug 21 16:36:14 IST 2021 WARN: This connection is using TLSv1.1 which is now deprecated and will be removed in a future release of Connector/J.
    Aug 21, 2021 4:36:14 PM org.hibernate.dialect.Dialect <init>
    INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
    Aug 21, 2021 4:36:14 PM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
    INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@411a5965] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
    Aug 21, 2021 4:36:14 PM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
    INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
    

    我在 hibernate.cfg.xml 文件中更改了这 3 行 -

        <!-- used MySQL5Dialect in place of MySQLDialect -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
        <!-- corrected the config. It must not be generating SQL statements because of it -->
        <property name="show_sql">true</property>
    

    请注意,生成的日志现在有primary key (aid)。如果您生成的 SQL 中存在此约束,那么它将按照您的预期开始抛出 ConstraintViolationException

    【讨论】:

    • 不。没用。我仍然可以看到重复的记录。 mysql&gt; select * from Alien; +------+---------+--------+ | aid | aname | acolor | +------+---------+--------+ | 103 | Mridula | Red | | 103 | Mridula | Red | | 103 | Mridula | Red | +------+---------+--------+ 3 rows in set (0.00 sec)
    • @Tanzeel 你能不能试着放下桌子重新开始。我怀疑由于已经重复的记录而无法更新架构。
    • 删除并重新创建了表。没用。我仍然能够一次又一次地保存相同的记录。
    • 是否可以进行 Skype 通话。我会分享屏幕。我的时区是印度班加罗尔
    • 你能更新你的问题中生成的模式吗?你在那里看到主键吗?
    【解决方案2】:

    请参考这个答案。 总之,您需要使用策略来生成 Id

    Duplicate values are inserted into table though @Id used for one of property in entity class in jpa

    【讨论】:

    • 感谢您的帮助,但这只是一种解决方法。如果我需要处理异常怎么办。我也会写测试用例。
    猜你喜欢
    • 1970-01-01
    • 2015-12-04
    • 1970-01-01
    • 1970-01-01
    • 2015-04-14
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    • 2015-09-27
    相关资源
    最近更新 更多