如何在使用Hibernate时使用注解来防止Mysql中的重复记录



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

Hibernate教程|配置文件

我小心翼翼地遵循每一步。我的问题是我能够多次推送相同的记录:

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]

请帮忙。

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

通过在jpa实体类中使用的属性之一的@Id将重复的值插入到表中

Hibernate 5.5.6.Final的正确休眠属性为hibernate.hbm2ddl.auto。请参阅这里的Hibernate文档。因此,请尝试替换您的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,正如您所期望的那样。

最新更新