I am getting an error I don't know how to resolve when running my basic contextLoads() test in spring boot
my pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.1</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.vweinert</groupId>
<artifactId>feddit-backend</artifactId>
<name>feddit-backend</name>
<description>backend for feddit</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-spatial</artifactId>
<version>6.1.6.Final</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
</dependency>
</dependencies>
<packaging>jar</packaging>
<build>
<finalName>backend</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
<version>2.28.0</version>
<configuration>
<!-- optional: limit format enforcement to just the files changed by this feature branch -->
<ratchetFrom>origin/master</ratchetFrom>
<formats>
<!-- you can define as many formats as you want, each is independent -->
<format>
<!-- define the files to apply to -->
<includes>
<include>*.md</include>
<include>.gitignore</include>
</includes>
<!-- define the steps to apply to those files -->
<trimTrailingWhitespace/>
<endWithNewline/>
<indent>
<tabs>true</tabs>
<spacesPerTab>4</spacesPerTab>
</indent>
</format>
</formats>
<!-- define a language-specific format -->
<java>
<!-- no need to specify files, inferred automatically, but you can if you want -->
<!-- apply a specific flavor of google-java-format and reflow long strings -->
<googleJavaFormat>
<version>1.8</version>
<style>AOSP</style>
<reflowLongStrings>true</reflowLongStrings>
</googleJavaFormat>
</java>
</configuration>
</plugin>
</plugins>
</build>
</project>
My test
package com.vweinert.fedditbackend;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class FedditBackendApplicationTests {
@Test
void contextLoads() {
}
}
The error on mvn test
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is java.lang.IllegalStateException: PostInitCallback queue could not be processed...
- PostInitCallbackEntry - Entity(com.vweinert.fedditbackend.entities.User) `sqmMultiTableInsertStrategy` interpretation
- PostInitCallbackEntry - Entity(com.vweinert.fedditbackend.entities.Comment) `sqmMultiTableInsertStrategy` interpretation
- PostInitCallbackEntry - Entity(com.vweinert.fedditbackend.entities.Post) `sqmMultiTableInsertStrategy` interpretation
My entities
User.java
package com.vweinert.fedditbackend.entities;
import java.time.LocalDateTime;
import java.util.Set;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.JoinTable;
import jakarta.persistence.Transient;
import jakarta.persistence.FetchType;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.hibernate.annotations.CreationTimestamp;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import com.vweinert.fedditbackend.request.auth.LoginRequest;
import com.vweinert.fedditbackend.request.auth.SignupRequest;
@Entity
@Table(name="users")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable=false,unique = true)
@NotBlank(groups = {SignupRequest.class}, message = "email is blank")
@Email(groups = {SignupRequest.class}, message = "invalid email")
private String email;
@Column(nullable=false,updatable = false,unique = true)
@NotBlank(groups = {LoginRequest.class, SignupRequest.class},message = "username is blank")
@Size(min = 8, max = 32, groups = {LoginRequest.class, SignupRequest.class}, message = "username must be between 8 and 32 characters")
private String username;
@Column(nullable=false)
@NotBlank(groups = {LoginRequest.class, SignupRequest.class},message = "Missing password")
@Size(min = 8, max = 32, groups = {LoginRequest.class, SignupRequest.class}, message = "password must be between 8 and 32 characters")
private String password;
@Column(columnDefinition = "text")
private String about;
@Column(nullable=false,updatable = false)
@CreationTimestamp
private LocalDateTime createdAt;
private LocalDateTime passwordChangedAt;
private LocalDateTime aboutChangedAt;
@Column(nullable = false)
@Builder.Default
private Boolean deleted = false;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable( name = "user_roles",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
@OneToMany(mappedBy = "user",fetch = FetchType.LAZY)
private Set<Post> posts;
@OneToMany(mappedBy = "user",fetch = FetchType.LAZY)
private Set<Comment> comments;
@Transient
@JsonInclude()
private String jwt;
public User(String username, String email, String password){
this.username = username;
this.email = email;
this.password = password;
}
}
Comment.java
package com.vweinert.fedditbackend.entities;
import java.time.LocalDateTime;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import org.hibernate.annotations.CreationTimestamp;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import com.vweinert.fedditbackend.request.comment.PostComment;
import com.vweinert.fedditbackend.request.comment.PutComment;
@Entity
@Table(name="comments")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Comment {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@NotNull(groups = {PutComment.class})
private Long id;
@Column(nullable=false,columnDefinition = "text")
@NotEmpty(groups = {PutComment.class, PostComment.class})
private String content;
@Column(nullable=false,updatable = false)
@CreationTimestamp
private LocalDateTime createdAt;
private LocalDateTime modifiedAt;
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name="post_id", referencedColumnName = "id")
private Post post;
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name="user_id", referencedColumnName = "id")
private User user;
@Column(nullable=false)
@Builder.Default
private Boolean deleted = false;
}
Post.java
package com.vweinert.fedditbackend.entities;
import java.time.LocalDateTime;
import java.util.List;
import com.vweinert.fedditbackend.request.post.PostPost;
import com.vweinert.fedditbackend.request.post.PutPost;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.Index;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.validation.constraints.NotBlank;
import org.hibernate.annotations.CreationTimestamp;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Table(name="posts", indexes = {@Index(name="on_created_at", columnList = "createdAt DESC")})
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable=false,updatable = false)
@NotBlank(groups = {PostPost.class},message = "Missing password")
private String title;
@Column(nullable=false,columnDefinition = "text")
@NotBlank(groups = {PutPost.class, PostPost.class},message = "Missing password")
private String content;
@Column(nullable=false,updatable = false)
@CreationTimestamp
private LocalDateTime createdAt;
private LocalDateTime modifiedAt;
@OneToMany(mappedBy = "post")
private List<Comment> comments;
@ManyToOne
@JoinColumn(name="user_id", referencedColumnName = "id")
private User user;
@Column(nullable=false)
@Builder.Default
private Boolean deleted = false;
}
application.properties in test folder
spring.datasource.url=jdbc:h2:mem:testdb
spring.jpa.hibernate.ddl-auto: update
I am expecting this test to pass. Note the use of the H2 database instead of postgres for my test. I recently updated this project from spring boot 2.7.6 to 3.0.1, so there have been quite a few issues. Not sure what to try to get this basic test to work.
Note when using postgres at regular runtime it works fine.
CodePudding user response:
added
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
Now my test works. I observed at spring-boot start that it was using postgres dialect, now it works with h2