【问题标题】:JPA Spring Entity Manager deletes entire table when doing a find commandJPA Spring Entity Manager 在执行查找命令时删除整个表
【发布时间】:2015-03-21 21:05:55
【问题描述】:

我遇到了一个非常奇怪的错误。我正在设置我的后端以使用 JPA/Spring/Hibernate。我能够连接到数据库,但每当我第一次访问表时,它会删除所有列和数据并将其替换为实体中的内容。

我只是在测试,所以我从表中选择了几个字段并在实体对象中表示它们,如下所示:

package xyz.data.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Users implements Serializable {

private static final long serialVersionUID = 4768962659322615643L;

@Id
@Column(name="UserID")
private String userID;
private String companyName;
private String userFName;
private String userName;

public String getUserID() {
    return userID;
}
public void setUserID(String userID) {
    this.userID = userID;
}
public String getCompanyName() {
    return companyName;
}
public void setCompanyName(String companyName) {
    this.companyName = companyName;
}
public String getUserFName() {
    return userFName;
}
public void setUserFName(String userFName) {
    this.userFName = userFName;
}
public String getUserName() {
    return userName;
}
public void setUserName(String userName) {
    this.userName = userName;
}

}

注意:我没有用 @Column 注释其他字段,因为我只是在测试。 我有一个 Spring 正在读取的资源文件:

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
xmlns:context="http://www.springframework.org/schema/context"  
xmlns:p="http://www.springframework.org/schema/p"   
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"  
xsi:schemaLocation="http://www.springframework.org/schema/beans  
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  
http://www.springframework.org/schema/context  
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
">  

<tx:annotation-driven />

<!-- Activates scanning of @Autowired -->
<context:annotation-config />

<!-- Activates scanning of @Repository, @Component and @Service -->
<context:component-scan base-package="ca.xyz.data" />
</beans>

And then I do a find command like this:

package abc.service.user;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;

import org.springframework.stereotype.Component;

import ca.impactauto.data.domain.Sale;
import ca.impactauto.data.domain.Users;

@Component
public class UserService {
@PersistenceContext private EntityManager em;


public void find() {
    //Users user = em.find(Users.class, "NNNC001118");
    Users user = em.find(Users.class, "STATIC");
    //return a column from finding STATIC.  STATIC is the primary key.
    System.out.println("UserInfo found: "+user.getCompanyName());

}

}

这里的“companyName”来自用户实体,它是用户表中的一列。

数据源:我正在使用 Tomcat 连接池:

package xyz.data.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.JdbcTemplate;

@Configuration
public class DataAccessConfiguration {

@Bean(destroyMethod = "close")
public javax.sql.DataSource getDatasource() {
org.apache.tomcat.jdbc.pool.DataSource ds = new   
org.apache.tomcat.jdbc.pool.DataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://10.10.161.11:3306/test_db?
zeroDateTimeBehavior=round");
ds.setUsername("downtown");
ds.setPassword("uptown");
ds.setInitialSize(5);
ds.setMaxActive(10);
ds.setMaxIdle(5);
ds.setMinIdle(2);
return ds;
}

@Bean public JdbcOperations tpl() {
    return new JdbcTemplate(getDatasource());
}
}

还有 JPA 实体管理器配置:

package ca.impactauto.data.configuration;

import java.util.Properties;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import    


org.springframework.dao.PersistenceExceptionTranslationPostProcessor;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import   
org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig {

@Autowired private DataAccessConfiguration dataAccessConfiguration;

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    LocalContainerEntityManagerFactoryBean em = new    
LocalContainerEntityManagerFactoryBean();
    em.setDataSource(dataSource());
    em.setPackagesToScan(new String[] {"xyz.data.domain"});
    JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    em.setJpaVendorAdapter(vendorAdapter);
    em.setJpaProperties(additionalProperties());
    return em;

}

@Bean
public DataSource dataSource(){
    return dataAccessConfiguration.getDatasource();

}

@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory  
emf){
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(emf);
    return transactionManager;

}

@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
   return new PersistenceExceptionTranslationPostProcessor();
}

Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
properties.setProperty("hibernate.dialect", 
"org.hibernate.dialect.MySQL5Dialect");
return properties;}}

find 命令运行后,它会清除所有现有数据和所有现有列,并将其替换为实体中的字段,但没有数据。即在这种情况下,实体中有 4 个字段,在查找之后,这 4 个字段将出现在表中,因为它们看起来与实体中的完全一样。

这是一个查找命令而不是整个表的删除命令!!有什么想法吗?

【问题讨论】:

  • 您是否配置了一些 DDL 模式生成选项?
  • 嗯,我从网上找到了这段代码,并没有注意到这个 hbmddl.auto 属性!那到底是什么?
  • 我只需要从后端读取。我可能还需要在某个时候坚持下去。我阅读了它,但这似乎是一种与部署一起使用以在数据库中创建一些基本状态的机制。我需要这个来阅读和写作。我应该把它拿出来吗??

标签: spring hibernate jpa


【解决方案1】:

我认为设置

properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");

告诉 hibernate 在启动时重新创建您的架构,然后在完成后将其删除(销毁所有内容)。这可能不是您想要的,因为我认为它适用于单元测试 DAO 等。

请参阅 herehere

【讨论】:

    【解决方案2】:

    问题可能与 DDL 模式生成选项有关,当设置选项 hbm2ddl.auto 时,它指示休眠根据实体的注释在数据库中生成表和列,因此您可以删除该属性.

    这可以用于您需要代码优先方法的场景,即您开始创建实体并根据您的类生成数据库架构。

    您还可以将属性值的值更改为 validate 它会针对您的实体验证架构,但不会修改数据库架构

    properties.setProperty("hibernate.hbm2ddl.auto", "validate");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-17
      • 1970-01-01
      • 1970-01-01
      • 2019-08-04
      • 1970-01-01
      • 2012-06-07
      • 2011-08-01
      相关资源
      最近更新 更多