1

I have run into a very strange error. I am setting up my backend to use JPA/Spring/Hibernate. I am able to connect to the database but whenever I access a table for the very first time, it deletes all columns and data and replaces it with what is in the entity.

I was just testing so I chose a few fields from the table and represented them in the entity object like so:

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;
}

}

NOTE: I did not annotate the other fields with @Column as I was just testing. I have a resources file which Spring is reading:

<?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());

}

}

Here "companyName" comes from the Users entity which is a column in the users table.

The datasource: I am using Tomcat Connection Pooling:

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());
}
}

And the JPA Entity manager config:

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;}}

After the find command runs, it wipes out ALL existing data and ALL existing columns and replaces it with the fields in the entity but with no data. i.e. in this case there are 4 fields in the entity and after the find, these same 4 fields will appear in the table as they look like exactly in the entity.

This is a find command NOT a delete command of an entire table!! Any ideas?

logixplayer
  • 939
  • 2
  • 13
  • 23
  • Have you configured some DDL schema generation option? – Cesar Loachamin Mar 21 '15 at 21:17
  • Hmm, I picked this code up from online and didn't notice this hbmddl.auto property! What is that exactly? – logixplayer Mar 21 '15 at 21:25
  • I simply need to read from the back end. I may need to persist at some point as well. I read up on it but this seems like a mechanism to use with a deploy to create some base state in the db. I need this for reading and writing. Should I just take it out?? – logixplayer Mar 21 '15 at 21:29

2 Answers2

2

I think that the setting

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

tells hibernate to re-create your schema at startup and then drop it (destroy everything) after it's done. That's probably not what you want, as I think it's meant for unit-testing DAOs and such.

See here and here.

Community
  • 1
  • 1
esaj
  • 15,875
  • 5
  • 38
  • 52
2

The problem could be relate a DDL schema generation option, when the option hbm2ddl.auto is set it indicates to the hibernate to generate the tables and columns in the database based in the annotations of the entities, so you can remove that property.

This could be used in scenarios where you want a code first approach were you start creating your entities and generating the database schema based on your classes.

You could also change the value of the value of the property to validate it validates the schema against your entities but it not modify the database schema

properties.setProperty("hibernate.hbm2ddl.auto", "validate");
Cesar Loachamin
  • 2,740
  • 4
  • 25
  • 33