0

I have a big problem.

First of all, this article doesn't seem to be related: Error creating bean with name 'entityManagerFactory' defined in class path resource : Invocation of init method failed

I tried that solution but it didn't work.

Also my sourcecode is here on github: https://github.com/drmgames5/M226b-LB

I'm Using VS Code on a linux VM.

So, let's come to the actual problem: When I try to start my Spring boot Application it doesn't work. I've searched for a solution but to be fair I don't even understand the Problem.

This is the output I get when starting the Project:

2020-06-15 22:11:41.132  INFO 9149 --- [  restartedMain] bztf.shopapi.DemoApplication             : Starting DemoApplication on m226B-lb1 with PID 9149 (/home/vagrant/M226b_LB1_V2/M226b-LB/shopapi/target/classes started by vagrant in /home/vagrant/M226b_LB1_V2/M226b-LB/shopapi)
2020-06-15 22:11:41.161  INFO 9149 --- [  restartedMain] bztf.shopapi.DemoApplication             : No active profile set, falling back to default profiles: default
2020-06-15 22:11:41.605  INFO 9149 --- [  restartedMain] o.s.b.devtools.restart.ChangeableUrls    : The Class-Path manifest attribute in /home/vagrant/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.2/jaxb-runtime-2.3.2.jar referenced one or more files that do not exist: file:/home/vagrant/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.2/jakarta.xml.bind-api-2.3.2.jar,file:/home/vagrant/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.2/txw2-2.3.2.jar,file:/home/vagrant/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.2/istack-commons-runtime-3.0.8.jar,file:/home/vagrant/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.2/stax-ex-1.8.1.jar,file:/home/vagrant/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.2/FastInfoset-1.2.16.jar,file:/home/vagrant/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.2/jakarta.activation-api-1.2.1.jar
2020-06-15 22:11:41.607  INFO 9149 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2020-06-15 22:11:41.607  INFO 9149 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2020-06-15 22:11:46.127  INFO 9149 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2020-06-15 22:11:46.556  INFO 9149 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 360ms. Found 2 JPA repository interfaces.
2020-06-15 22:11:50.608  INFO 9149 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2020-06-15 22:11:50.725  INFO 9149 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-06-15 22:11:50.725  INFO 9149 --- [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.31]
2020-06-15 22:11:51.304  INFO 9149 --- [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-06-15 22:11:51.304  INFO 9149 --- [  restartedMain] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 9697 ms
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
2020-06-15 22:11:52.254  INFO 9149 --- [  restartedMain] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
2020-06-15 22:11:52.608  INFO 9149 --- [  restartedMain] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 5.4.12.Final
2020-06-15 22:11:53.181  INFO 9149 --- [  restartedMain] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
2020-06-15 22:11:53.711  INFO 9149 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2020-06-15 22:11:53.765  WARN 9149 --- [  restartedMain] com.zaxxer.hikari.util.DriverDataSource  : Registered driver with driverClassName=com.mysql.jdbc.Driver was not found, trying direct instantiation.
2020-06-15 22:11:54.824  INFO 9149 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2020-06-15 22:11:54.869  INFO 9149 --- [  restartedMain] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
2020-06-15 22:11:55.798  WARN 9149 --- [  restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: bztf.shopapi.model.Product, at table: order, for columns: [org.hibernate.mapping.Column(product)]
2020-06-15 22:11:55.800  INFO 9149 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2020-06-15 22:11:55.834  INFO 9149 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
2020-06-15 22:11:55.837  INFO 9149 --- [  restartedMain] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2020-06-15 22:11:55.862  INFO 9149 --- [  restartedMain] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-06-15 22:11:55.868 ERROR 9149 --- [  restartedMain] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: bztf.shopapi.model.Product, at table: order, for columns: [org.hibernate.mapping.Column(product)]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
AbstractAutowireCapableBeanFactory.java:1796
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
AbstractAutowireCapableBeanFactory.java:595
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
AbstractAutowireCapableBeanFactory.java:517
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
AbstractBeanFactory.java:323
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
DefaultSingletonBeanRegistry.java:222
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
AbstractBeanFactory.java:321
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
AbstractBeanFactory.java:202
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1108) ~[spring-context-5.2.4.RELEASE.jar:5.2.4.RELEASE]
AbstractApplicationContext.java:1108
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868) ~[spring-context-5.2.4.RELEASE.jar:5.2.4.RELEASE]
AbstractApplicationContext.java:868
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.2.4.RELEASE.jar:5.2.4.RELEASE]
AbstractApplicationContext.java:550
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) ~[spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
    at bztf.shopapi.DemoApplication.main(DemoApplication.java:17) ~[classes/:na]
DemoApplication.java:17
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.2.5.RELEASE.jar:2.2.5.RELEASE]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: bztf.shopapi.model.Product, at table: order, for columns: [org.hibernate.mapping.Column(product)]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:403) ~[spring-orm-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:378) ~[spring-orm-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1855) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
AbstractAutowireCapableBeanFactory.java:1855
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1792) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
AbstractAutowireCapableBeanFactory.java:1792
    ... 21 common frames omitted
Caused by: org.hibernate.MappingException: Could not determine type for: bztf.shopapi.model.Product, at table: order, for columns: [org.hibernate.mapping.Column(product)]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:488) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:455) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.hibernate.mapping.Property.isValid(Property.java:227) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:624) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.hibernate.mapping.RootClass.validate(RootClass.java:267) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:351) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:464) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1237) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:391) ~[spring-orm-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    ... 25 common frames omitted

Does anybody understand the problem? Or even better does someone know a solution?

And if the before mentioned article is actually about the same problem: do I need to do something else with the dependencies than add them to the pom.xml?

I'm very Thankful for every help I can get.

drmgames
  • 29
  • 4
  • 1
    JPA entities must have a no-args constructor (unless something has changed that I don't know about). Your classes `Order` and `Product` both don't have a no-args constructor. – Jesper Jun 15 '20 at 21:48

1 Answers1

2

Edit: updated to OneToMany

From the error:

org.hibernate.MappingException: Could not determine type for: bztf.shopapi.model.Product, at table: order, for columns: [org.hibernate.mapping.Column(product)]

It's missing the mapping between Product and Order.

Tested quickly with your code using a one to many mapping and it worked (use the mapping that is more suitable to your business logic of course). For example:

Product.java:

package bztf.shopapi.model;

import javax.persistence.*;
import javax.validation.constraints.NotBlank;

@Entity // Das sagt Hibernate, dass es einen Tabelle in der Datenbank anlegen soll
@Table(name = "products")
public class Product {

@Id // ID 
@GeneratedValue(strategy = GenerationType.AUTO) // Autoincrement
private long id;

@NotBlank(message = "Name is mandatory") // NOT NULL
@Column(name = "name") // Name der Column
private String name;

@NotBlank(message = "Price is mandatory") // NOT NULL
@Column(name = "price") // Name der Column
private double price;

@Column(name = "stock") // Name der Column
private int stock;

@NotBlank(message = "Image Path is mandatory") // NOT NULL
@Column(name = "img") // Name der Column
private String img; //Dies ist nur der Pfad zum Bild, bzw der Name des Bildes

public long getId() {
    return this.id;
}

public void setName(String name){
    this.name = name;
}

public String getName(){
    return this.name;
}

public void setPrice(double price){
    this.price = price;
}

public double getPrice(){
    return this.price;
}

public void setStock(int stock){
    this.stock = stock;
}

public int getStock(){
    return this.stock;
}
public void setImg(String img){
    this.img = img;
}
public String getImg(){
    return img;
}
}

Order.java:

package bztf.shopapi.model;

import javax.persistence.*;
import javax.validation.constraints.NotBlank;

/**
* Entity : Order
*/
@Entity // Das sagt Hibernate, dass es einen Tabelle in der Datenbank anlegen soll
@Table(name = "order")
public class Order {

@Id // ID 
@GeneratedValue(strategy = GenerationType.AUTO) // Autoincrement
private long id;

@OneToMany
@JoinColumn(name = "order_id")
private List<Product> products;

@Column(name = "qty") // Name der Column   -> qty = quantity
private int qty;

@Column(name = "price") // Name der Column
private double price;

public long getId() {
    return this.id;
}

public void setQty(int qty){
    this.qty = qty;
    // this won't make sense anymore because you have a list of Products for your order
    // You can calculate the price by adding all prices for all the order products
    //this.price = Double.valueOf(this.qty) * product.getPrice();
}

public int getQty(){
    return this.qty;
}

public double getPrice(){
    return this.price;
}

public List<Product> getProducts() {
    return products;
}

public void setProducts(List<Product> products) {
    this.products = products;
}
}

A reference for one to many mapping: https://www.baeldung.com/hibernate-one-to-many

Note that I also added table names as you will run into a MySQL reserved keyword issue with your order table (order is a reserved keyword)

Henrique Forlani
  • 1,325
  • 9
  • 22
  • Thank you very much, that's very helpful :D Now I got one new Question: Does this mean that the order is also referenced in the product? Because I want only the Order to reference the Product but not the other way around. Because I want a Product to be able to be referenced by many orders, but I see no sense in referencing the Order from the product. It doesn't need to know about the order. – drmgames Jun 16 '20 at 09:32
  • 1
    @drmgames so the relation in your case would be: one order can have many products? If so, I can update my answer, because you would need a OneToMany association. – Henrique Forlani Jun 16 '20 at 10:21
  • Exactly, would I have to change only the annotation? Or is there more to be changed? – drmgames Jun 16 '20 at 13:02
  • @drmgames I updated my answer with your requirements. The relationship is now unidirectional, meaning that 1 Order can have 0..N Products, but there is no reference to orders in products. Note that for some of your methods, for example to calculate the total price, you will need to update your logic, to go through all products. Hope this helps. – Henrique Forlani Jun 16 '20 at 14:40
  • That is so cool, I thank you so much. You really saved me :D Didn't expect a quick enough answer in Stack Overflow. BTW: I noticed that you got rid of the Constructors, are they not needed? – drmgames Jun 16 '20 at 14:48
  • @drmgames it's a JPA requirement to have a no-arg constructor. You can find out more about how to design a nice entity. Btw, can you mark this is answered? – Henrique Forlani Jun 16 '20 at 14:50
  • Do you know a good tutorial or example for nice entities? I didn't find something useful but I would really like to make better entities and to understand them better. – drmgames Jun 18 '20 at 20:46
  • @drmgames regarding the code that you shared here, my only comment would be about naming (always follow java naming conventions and use descriptive names for variables, classes, etc) as I don't know your business logic. – Henrique Forlani Jun 19 '20 at 19:34
  • @drmgames As something to think about, and that is maybe what you are looking for, normally you will see that entities are POJOs (check examples in spring documentation) , with little or no business logic at all, which is something also called sometimes as anemic domain model. Some people consider this an anti pattern, because it breaks OO principles, because it segregates logic and data, so that your logic ends up in Service classes. A nice reference from Martin Fowler: https://martinfowler.com/bliki/AnemicDomainModel.html – Henrique Forlani Jun 19 '20 at 19:35
  • @drmgames the opposite of the anemic domain model would be to have all your logic in your domain, which is something called a rich domain model. It's more common in spring projects however, to see entities as POJOs and rich service classes (anemic domain model). You can even try to find a balance between them: https://dzone.com/articles/anemic-domain-model-in-typical-spring-projects-1 . Anyway, I hope I have not confused you, but you are the right path, making the right questions, good luck. – Henrique Forlani Jun 19 '20 at 19:39
  • Thank you very much for your tipps and help. I will look through it. :D – drmgames Jun 23 '20 at 12:46