Spring boot with H2 - Not a managed type - spring-boot

I am having a problem while starting my Spring Boot application:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'coffeeService': Unsatisfied dependency expressed through field 'coffeeRepository': Error creating bean with name 'coffeeRepository' defined in com.coffeetime.coffeeshop.repository.CoffeeRepository defined in #EnableJpaRepositories declared on CoffeeshopApplication: Not a managed type: class com.coffeetime.coffeeshop.domain.Coffee
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'coffeeRepository' defined in com.coffeetime.coffeeshop.repository.CoffeeRepository defined in #EnableJpaRepositories declared on CoffeeshopApplication: Not a managed type: class com.coffeetime.coffeeshop.domain.Coffee
Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.coffeetime.coffeeshop.domain.Coffee
The version of Spring Bot is 3.0 and Java is 17 (Most updated ones from Initialzr).
I want to use H2 as in-memory database:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
The package hierarchy is convenient to scan entities. So, I think it is not necessary to add #EntityScan (I tried it as well)
File structure
Here is application.properties:
spring.datasource.url=jdbc:h2:mem:coffeeshopdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=pass1234
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.show-sql=true
spring.h2.console.enabled=true
spring.jpa.defer-datasource-initialization=true
Repository
import org.springframework.data.jpa.repository.JpaRepository;
import com.coffeetime.coffeeshop.domain.Coffee;
public interface CoffeeRepository extends JpaRepository<Coffee, Long>{
}
And the entity:
#Entity
#Table(name = "coffee")
public class Coffee {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#Column(name = "name")
#NotEmpty(message = "Coffee name cannot be empty")
private String name;
#Column(name = "amount")
#NotNull(message = "Coffee price cannot be empty")
#Min(value = 0, message = "Coffee price must be greater than or equal to 0")
private BigDecimal amount;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
}
I checked the similar problem in this thread, no any answer worked. I suspect about H2.
Thanks
I tried using #EntityScan and playing with application.properties. But still same error.

I found the problem. Spring Boot 3.0.0 version started using jakarta instead of javax.persistence. Reorganizing the imports solved the problem.

Related

Quarkus Reactive with Vert.x and Hibernate Reactive / java.lang.NullPointerException: Cannot store to object array because "this.loadedState" is null

i am trying to use quarkus reactive with vert.x and hibernate reactive.
this is my pom.xml:
<quarkus-plugin.version>1.12.2.Final</quarkus-plugin.version>
and
<quarkus.platform.version>1.12.2.Final</quarkus.platform.version>
with:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-reactive-mysql-client</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-web</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-reactive</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-reactive-pg-client</artifactId>
</dependency>
this is my application.properties file:
# postgres-configuration
quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=partner_usr
quarkus.datasource.password=postgrespw
quarkus.datasource.reactive.url=vertx-reactive:postgres://localhost:3310/partnerdb
# test, but not working (schema's won't created)
quarkus.hibernate-orm.database.generation.create-schemas=true
# working (drop-and-create only on mysql, not on postgres)
quarkus.hibernate-orm.database.generation=drop-and-create
quarkus.hibernate-orm.log.sql=true
quarkus.http.cors=true
Then, i have following entities:
#Data
#MappedSuperclass
public abstract class IdEntity {
#Id
#SequenceGenerator(name = "entitySeq", sequenceName = "entitiy_id", allocationSize = 1, initialValue = 5)
#GeneratedValue(generator = "entitySeq", strategy = GenerationType.AUTO)
private Long id;
}
#Data
#Entity
#EqualsAndHashCode(callSuper = true)
public class Person extends IdEntity {
private String firstName;
private String lastName;
public Person() {
}
#ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Address personAddress;
}
#Data
#Entity
#EqualsAndHashCode(callSuper = true)
public class Address extends IdEntity {
private String street;
private String houseNumber;
private int postalCode;
private String city;
#OneToMany(orphanRemoval = true, mappedBy = "personAddress", fetch = FetchType.LAZY)
private List<Person> persons = new ArrayList<>();
public Address() {
}
}
Now, i am calling a reactive web-service with a reactive db access:
#Path("/person")
#ApplicationScoped
public class PersonResource {
#Inject
io.vertx.mutiny.pgclient.PgPool sqlClient;
#Inject
Mutiny.Session mutinySession;
#GET
//#Produces(MediaType.APPLICATION_JSON)
#Path("/list-persons")
#Route(path = "/list-persons", methods = HttpMethod.GET, produces = MediaType.APPLICATION_JSON)
#Transactional
public Multi<Person> listAllPersons() {
// return sqlClient.query("SELECT * FROM Person ORDER BY lastName ASC").execute()
// .onItem().transformToMulti(set -> Multi.createFrom().iterable(set))
// .onItem().transform(this::transformPersons);
return mutinySession.createQuery("SELECT f FROM Person f ORDER BY f.lastName")
.getResults().onItem().transform(this::transformObject);
}
private Person transformObject(Object f) {
return (Person)f;
}
private List<Object> transformPersons(Object f) {
final Person person = (PartnerMockEntity)f;
final List<Object> bogus = new ArrayList<>();
bogus.add(partner);
return bogus;
}
}
Exception:
Resulted in: com.fasterxml.jackson.databind.JsonMappingException: Cannot store to object array because "this.loadedState" is null (through reference chain: de.subito.model.Person["personAddress"]->de.subito.model.Address["person"])
I tried to use :
FetchType.EAGER on Address in Person
I removed the #OneToMany Relation in Address: this solves the error (yay), but the addresses won't be returned in the resulting json (id is existing, but the values are not fetched)
The questions is, how can i fetch in reactive those kind of relations without getting errors?
Or do i need a angular page in order to display this correctly?
Somehow i forgot about how fetchType.Lazy works.
Simply add a join fetch into the hql and everything works as expected.
SELECT p from Person p left join fetch p.personAddress
When using this query, there's no session/closed or any other exception thrown and the json result will be displayed as expected.
Additional note: in order to avoid recursive serialization, it is required to use the
#JsonManagedReference and #JsonBackReference
Annotations, depending on your needs to your relations.

lombok #Data not generating getters and setters

I am using #Data annotation on my entity class.
#Data public class Test {
private String name;
private String lName;
I am using the latest lombok dependency
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
The class file after maven compile/package look like this
package ******.models;
public class Test {
private String name;
private String lName;
public Test() {
}
Any idea on this error?Using IntelliJ IDEA as my IDE where lombok plugin is active
Most likely your annotation processing in IntelliJ is off. You can turn it on by referring to the following image

Spring Boot: At least one JPA metamodel must be present

Hello everyone,
I have a problem when I run my project
Caused by: java.lang.IllegalArgumentException: At least one JPA metamodel must be present!
I don't know how to fix it.I saw some same topic and They said this problem in file pom.xml. But I don't see anything wrong in my file pom.xml. So Can somebody help me
This is my Code
File pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
DemoApplication
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
Model with #Entity
package com.example.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "contact")
public class Contact implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", nullable = false)
private int id;
#Column(name = "name", nullable = false)
private String name;
#Column(name = "email")
private String email;
#Column(name = "phone")
private String phone;
public Contact() {
super();
}
public Contact(int id, String name, String email, String phone) {
super();
this.id = id;
this.name = name;
this.email = email;
this.phone = phone;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
I don't know how to fix it
You have in your pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
But you don't have any classes with #Entity annotation defined. You need at least one of those to successfully create the Entity Manager. If not remove the above dependency.
Your SpringBootApplication relies in package com.example.demo; and your entity in package com.example.model; . Per Default #SpringBootApplication will try to look into its package and below. It cannot find your entities as they are in a different package, unless you specify it explicitly e.g. via
#EntityScan(basePackages = "com.example.model")

swagger springfox - bean validation JSR 303 not recognize

I followed this tutorial https://springframework.guru/spring-boot-restful-api-documentation-with-swagger-2/ to generate a swagger documentation.
It's working but when I try to add some validation in my bean I don't find the information in the documentation:
#ApiOperation(value = "Creates a product",
notes="Populates a product instance bla bla")
#RequestMapping(value = "/add", method = RequestMethod.POST, produces = "application/json")
public ResponseEntity saveProduct( #Valid #RequestBody Product product){
productService.saveProduct(product);
return new ResponseEntity("Product saved successfully", HttpStatus.OK);
}
My entity with the validations annotations :
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
// #ApiModelProperty(notes = "The database generated product ID")
private Integer id;
#Version
// #ApiModelProperty(notes = "The auto-generated version of the product")
#NotNull
private Integer version;
// #ApiModelProperty(notes = "The application-specific product ID" )
private String productId;
// #ApiModelProperty(notes = "The product description")
#NotBlank
#Size(max = 50)
private String description;
// #ApiModelProperty(notes = "The image URL of the product")
private String imageUrl;
// #ApiModelProperty(notes = "The price of the product", required = true)
#NotNull
private BigDecimal price;
But when I check the documentation I don't have those validation information:
Here https://github.com/springfox/springfox/issues/987 they say that we need to update our dependencies and it's what I did :
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
Did I miss something in the configuration? Any idea to help me ?
I found the solution in this post : http://vojtechruzicka.com/documenting-spring-boot-rest-api-swagger-springfox/.
All is explained :
Unfortunately, JSR-303 based documentation does not work out of the box, you need an additional dependency:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<version>2.8.0</version>
</dependency>
And you need to import BeanValidatorPluginsConfiguration configuration file on top of your swagger configuration class:
#Configuration
#EnableSwagger2
#Import(BeanValidatorPluginsConfiguration.class)
public class SpringFoxConfig {
...
}
Thank you #vojtech-ruzicka https://stackoverflow.com/users/4560142/vojtech-ruzicka

Can't save "Many"-Entity of #OneToMany with Spring-Boot & Spring-JPA

I'm using Spring Boot and MySQL. I followed this link for setting everything up and I'm able to connect to MySql and read/write data. But there is an 1:n-relationship and I'm not able to save entities of the many side:
#Entity
public class OneSideOfRelationship {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long oneId;
private String someText;
#OneToMany(mappedBy="oneId")
private List<ManySideOfRelationship> manySide;
[Constructor / Getter / Setter]
}
#Entity
public class ManySideOfRelationship {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long manyId;
#ManyToOne(targetEntity=OneSideOfRelationship.class)
#JoinColumn
private long oneId;
private String someMoreText;
[Constructor / Getter / Setter]
}
#Transactional
public interface OneDao extends CrudRepository<OneSideOfRelationship, Long> {}
#Transactional
public interface ManyDao extends CrudRepository<ManySideOfRelationship, Long> {}
If I do this in my controller:
[...]
#Autowired
#private ManySideOfRelationship manyDao;
[...]
ManySideOfRelationship many = new ManySideOfRelationship();
many.setOneId(1L);
many.setSomeMoreText("Text");
manyDao.save(many);
[...]
I got:
org.springframework.orm.jpa.JpaSystemException: could not get a field value by reflection getter of com.package.database.OneSideOfRelationship.oneId; nested exception is org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.package.database.OneSideOfRelationship.oneId
Out of my application.properties:
spring.datasource.url = jdbc:mysql://myurl:myport/mydatabase
spring.datasource.username = myusername
spring.datasource.password = mypassword
spring.jpa.hibernate.ddl-auto = update
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
And something out of pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
Hope somebody has an idea.
The oneId must be datatype of OneSideOfRelationship not long.
#ManyToOne(targetEntity=OneSideOfRelationship.class)
#JoinColumn
private OneSideOfRelationship oneId;

Resources