hibernate - database not updated using JPA and spring when new entries are made -
i configuring simple jpa application using spring framework. goal populate db data during junit test runs. understand not ideal. want different purposes.
here persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"> <persistence-unit name="tothought-tutorial-test" transaction-type="resource_local"> <provider>org.hibernate.ejb.hibernatepersistence</provider> <properties> <!-- <property name="hibernate.dialect" value="org.hibernate.dialect.h2dialect" /> <property name="hibernate.hbm2ddl.auto" value="create-drop" /> --> <property name="hibernate.dialect" value="org.hibernate.dialect.mysql5dialect" /> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.show_sql" value="true"/> </properties> </persistence-unit> </persistence>
test-context.xml
<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemalocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.2.xsd"> <!-- database --> <!-- <jdbc:embedded-database id="datasource" type="h2"></jdbc:embedded-database> --> <bean id="datasource" class="org.springframework.jdbc.datasource.drivermanagerdatasource"> <property name="driverclassname" value="com.mysql.jdbc.driver" /> <property name="url" value="jdbc:mysql://localhost:3306/to_thought_tutorial" /> <property name="username" value="demo" /> <property name="password" value="demo" /> </bean> <!-- entity manager --> <bean id="entitymanagerfactory" class="org.springframework.orm.jpa.localcontainerentitymanagerfactorybean"> <property name="datasource" ref="datasource" /> <property name="persistenceunitname" value="tothought-tutorial-test" /> </bean> <!-- transaction manager --> <bean id="transactionmanager" class="org.springframework.orm.jpa.jpatransactionmanager"> <property name="entitymanagerfactory" ref="entitymanagerfactory" /> </bean> <!-- jpa repositories --> <jpa:repositories base-package="com.cloudfoundry.tothought.repositories"></jpa:repositories> </beans>
here junittest
class
@runwith(springjunit4classrunner.class) @contextconfiguration(locations="classpath:meta-inf/test-context.xml") @transactional public class postpartrepositorytest { @autowired postpartrepository repository; @test public void test() { postpart postpart = new postpart(); string body = "hello"; postpart.setbody(body); repository.save(postpart); postpart dbpostpart = repository.findone(postpart.getpostpartid()); assertnotnull(dbpostpart); assertequals(body, dbpostpart.getbody()); } @test public void inserttest(){ post post = new post(); post.setpostdate(new date()); post.settitle("first post"); postpart postpart = new postpart(); string body = "hello"; postpart.setbody(body); postpart.setpost(post); repository.save(postpart); postpart dbpostpart = repository.findone(postpart.getpostpartid()); assertnotnull(dbpostpart); assertnotnull(dbpostpart.getpost()); assertequals(body, dbpostpart.getbody()); } }
both test passes. not see entry in tables, although tables created first time.
you won't see entries because running test @transactional
using springjunit4classrunner
. default running tests @transactional
database changes automatically rolled once test finished. more information see question here
the order in these things happen follows:
- test starts, setup scripts run, creates tables.
- tests start running in transactional context.
- tests finish running, , database changes made during test, automatically rolled back, leaving database in state in before tests ran.
you can change default behaviour can use @transactionconfiguration(defaultrollback=false)
@ top of class. bad practice because unit tests should not depend on each other , shouldn't permanently modifying application state. also, if depending on 1 test set in environment , use in next test, there no guarantee order tests executed test runner.