can you please explain me what i do wrong. I Am learning JPA and i'm stuck with tests. On the first test "teslaOne" i create and persist Entity to the db and i would like to get access to this data from second test "teslaTwo".
When i use Persistence.createEntityManagerFactory("h2database") it works but when i store it on the memoty Persistence.createEntityManagerFactory("in.memory.test") it does not.
i understand that "h2database" it is a fila, "in.memory.test" memory but it not clear for me why it have a different behavior and why it nullify data.
Can you tell me please how to share EntityManager between tests.
persistence.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="3.0"
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd">
<persistence-unit name="h2database" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.caveatemptor.core.data.entites.Tesla</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.connection.url" value="jdbc:h2:file:./h2data/demodb"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
<persistence-unit name="in.memory.test" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.caveatemptor.core.data.entites.Tesla</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.url" value="jdbc:h2:mem:"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="false"/>
</properties>
</persistence-unit>
</persistence>
Tesla.java
@Setter
@Getter
@ToString
@Entity()
public class Tesla implements Serializable {
@Id
@GeneratedValue
protected Long ID;
protected String vehicle;
}
TeslaTest.java
package com.caveatemptor.core.data.inheritance;
import com.caveatemptor.core.data.entites.Tesla;
import jakarta.persistence.*;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class TeslaTest {
// private final EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("h2database");
private final EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("in.memory.test");
@Test
void teslaOne(){
Tesla tesla = new Tesla();
tesla.setVehicle("Model X");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
try {
transaction.begin();
entityManager.persist(tesla);
transaction.commit();
Tesla teslaV = entityManager.find(Tesla.class, tesla.getID());
assertEquals(teslaV.getVehicle(), "Model X");
}
finally {
if(transaction.isActive()){
transaction.rollback();
}
entityManager.close();
}
}
@Test
void teslaTwo(){
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
try {
transaction.begin();
TypedQuery<Tesla> query = entityManager.createQuery("select t from Tesla t", Tesla.class);
List<Tesla> items = query.getResultList();
assertEquals(1, items.size());
}
finally {
if(transaction.isActive()){
transaction.rollback();
}
entityManager.close();
}
}
}
It makes sense that it’s not keeping the same in memory database as, without really knowing much about it, I assume it works much the same as objects and is stored in the heap. When you call createEntityManager()
the second time, it’s like creating a new object and the reference points to the new object, leaving the old one to get cleaned up by the GarbageCollector.
To prevent having to initialize the in memory database a second time, I believe setting it up as a @BeforeAll
should do the trick.
private final EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("in.memory.test");
private EntityManager entityManager;
@BeforeAll
void setup() {
entityManager = entityManagerFactory.createEntityManager();
}