I am encountering an error in a simple JPA unit test where it attempts to execute an ALTER TABLE
command on a table that it claims does not exist. Here is the relevant error message:
INFO: Property datanucleus.metadata.validate unknown - will be ignored
Jul 22, 2024 12:02:25 PM org.datanucleus.store.rdbms.table.AbstractTable executeDdlStatementList
SEVERE: Error thrown executing ALTER TABLE USERS ADD COLUMN ATTRIBUTES VARCHAR(255) NULL : Table "USERS" not found; SQL statement:
ALTER TABLE USERS ADD COLUMN ATTRIBUTES VARCHAR(255) NULL [42102-200]
org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "USERS" not found; SQL statement:
ALTER TABLE USERS ADD COLUMN ATTRIBUTES VARCHAR(255) NULL [42102-200]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:453)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
at org.h2.message.DbException.get(DbException.java:205)
at org.h2.message.DbException.get(DbException.java:181)
at org.h2.command.ddl.AlterTableAlterColumn.update(AlterTableAlterColumn.java:114)
at org.h2.command.CommandContainer.update(CommandContainer.java:198)
at org.h2.command.Command.executeUpdate(Command.java:251)
at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:228)
at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:201)
at org.datanucleus.store.rdbms.table.AbstractTable.executeDdlStatement(AbstractTable.java:860)
With this unit test:
UserRepositoryTest.java
public class UserRepositoryTest {
private EntityManagerFactory emf;
private EntityManager em;
UserRepository userRepository;
@Before
public void setUp() {
emf = Persistence.createEntityManagerFactory("test-pu");
em = emf.createEntityManager();
userRepository = new UserRepository(em);
}
@After
public void tearDown() {
em.getTransaction().begin();
em.createQuery("DELETE FROM User u").executeUpdate();
em.getTransaction().commit();
if (em != null && em.isOpen()) {
em.close();
}
if (emf != null && emf.isOpen()) {
emf.close();
}
}
@Test
public void testCreateUser() {
}
}
Here are the relevant parts of my setup:
UserRepository.java
public class UserRepository extends AbstractRepository<User> {
private static final EntityManagerFactory emf = createEntityManagerFactory();
public UserRepository() {
super(User.class, createEntityManager());
}
public UserRepository(EntityManager entityManager) {
super(User.class, entityManager);
}
private static EntityManagerFactory createEntityManagerFactory() {
// TODO: Change to "prod-pu" when the persistence config has been fixed
return Persistence.createEntityManagerFactory("test-pu");
}
private static EntityManager createEntityManager() {
return emf.createEntityManager();
}
}
User.java
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int userId;
@Column(name = "username", nullable = false, unique = true)
private String username;
@Column(name = "password_hash")
private String passwordHash;
@Column(name = "google_id", unique = true)
private String googleId;
@Column(name = "email", nullable = false, unique = true)
private String email;
@Column(name = "attributes")
private String attributes;
@ManyToOne
@JoinColumn(name = "subscription_id", nullable = true)
private Subscription subscription;
@Column(name = "created_at", nullable = false, updatable = false)
private Timestamp createdAt;
@Column(name = "updated_at", nullable = false)
private Timestamp updatedAt;
persistence.xml
<persistence-unit name="test-pu" transaction-type="RESOURCE_LOCAL">
<provider>org.datanucleus.api.jpa.PersistenceProviderImpl</provider>
<class>com.mycompany.core.subscription.model.Subscription</class>
<class>com.mycompany.core.user.model.User</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"/>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.user" value="sa"/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="datanucleus.schema.autoCreateAll" value="true"/>
<property name="datanucleus.connectionPoolingType" value="None"/>
<property name="datanucleus.schema.validateAll" value="false"/>
<property name="datanucleus.metadata.validate" value="false"/>
<property name="datanucleus.log.level" value="DEBUG"/>
</properties>
</persistence-unit>
The error suggests that the USERS
table cannot be found during the execution of an ALTER TABLE
statement. However, the table should be created automatically by the DataNucleus ORM as specified in the persistence.xml
file.
What could be causing this issue and how can I resolve it?