为什么hibernate会话保存更新行而不是插入行?

问题描述 投票:0回答:1

我在windows7x64上安装了Postgres 10.1版。我有一个数据库“postgres”,其中包含一个表“dbuser”和列“user_id”和“username”。我正在使用Intelij和Maven。我正在使用来自hibernate的Session来尝试在表中插入一行。

app.Java

package com.hibernateTest;

import org.hibernate.Session;

public class App {
    public static void main(String[] args) {
        Session session = HibernateUtil.getSessionFactory().openSession();
    session.beginTransaction();
    dbuser dbuser = new dbuser();
    dbuser.setUser_id(556);
    dbuser.setUsername("waaagr");       
    session.save(dbuser);
    //session.merge(dbuser);//my mistake---old code
    session.getTransaction().commit();
    }
}

hibernate UT IL.Java

package com.hibernateTest;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

    private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
            return new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public static void shutdown() {
        getSessionFactory().close();
    }

}

倒不是而.Java:

    package com.hibernateTest;

import javax.persistence.*;

@Entity
@Table(name = "dbuser")
public class dbuser implements java.io.Serializable {

    @Id
    //@GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name = "user_id")
    private long user_id;

    @Column(name = "username")
    private String username;


    public dbuser() {
    }

    public dbuser(long user_id, String username) {
        this.user_id = user_id;
        this.username = username;
    }

    @Column(name = "username")
    public String getUsername() {
        return this.username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Column(name = "user_id")
    public long getUser_id() {
        return user_id;
    }

    public void setUser_id(long user_id) {
        this.user_id = user_id;
    }
}

的hibernate.cfg.xml

<!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.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
        <property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
        <property name="hibernate.connection.username">postgres</property>
        <property name="hibernate.connection.password">password</property>
        <property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/mydb</property>
        <property name="connection_pool_size">1</property>
        <property name="hbm2ddl.auto">create</property>
        <property name="show_sql">true</property>
        <mapping class="com.hibernateTest.User"/>
    </session-factory>
</hibernate-configuration>

pom.hml

<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 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mkyong.common</groupId>
    <artifactId>HibernateExample</artifactId>
    <packaging>jar</packaging>
    <version>1.0</version>
    <name>HibernateExample</name>
    <url>http://maven.apache.org</url>
    <repositories>
        <repository>
            <id>JBoss repository</id>
            <url>http://repository.jboss.org/nexus/content/groups/public/</url>
        </repository>
    </repositories>
    <dependencies>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>9.4-1203-jdbc4</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>3.6.3.Final</version>
        </dependency>
        <dependency>
            <groupId>javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.12.1.GA</version>
        </dependency>
    </dependencies>
</project>

问题是当我运行我的应用程序时,我得到了:

Hibernate: select dbuser0_.user_id as user1_0_0_, dbuser0_.username as username0_0_ from dbuser dbuser0_ where dbuser0_.user_id=?
Hibernate: insert into dbuser (username, user_id) values (?, ?)

奇怪的第一件事是终端中有(?,?)的值。并且数据库中的表中的数据只是更新,但是我想插入一个新行而不是更新一行?我不是为什么这段代码更新一行而不是插入一个新行,一个新行?非常感谢你。

java postgresql hibernate maven java-ee-7
1个回答
0
投票
dbuser dbuser = new dbuser();
dbuser.setUser_id(556);
dbuser.setUsername("waaagr");       
session.merge(dbuser);

所以你在这里做的是告诉hibernate一些id = 556的用户可能存在于数据库中,并且你想将你的更改合并到数据库中。这就是所谓的分离实体。

合并正在进行的是通过提供的id(因此SELECT)获取给定实体,检查数据库和对象中的数据之间是否存在某些差异,并在“脏字段”上提交UPDATE操作。同时,merge将返回被管实体。这就是根据JPA规范的merge的工作原理。

在你的情况下,你已经谎称休眠这样的实体已经存在,但是Hibernate知道这个(因为为ID fetch设置的空结果)并且它执行INSERTUPDATE

所以要将它包装起来:通过提供ID,您可以指示给定的实体应该存在于数据库中并且可以进行合并。如果您想创建新用户(即使使用给定的id),请使用save merge

© www.soinside.com 2019 - 2024. All rights reserved.