0

I made an application/website were you can rate movies and see the ranking of the movies based on the ratings given by the users.

I first made the application without a connection with the database and had a class with some mock data for testing the application. Now I want to start connecting with my MySQL database and I got the following error. I am making this app for a school project so I only have examples where we connect an easy class with only Strings or Integers with the database but I don't know what to do to solve this error.

The map contains names of users and the rating they gave to the movie.

Film class

package domain;

import java.io.Serializable;
import java.util.Map;
import java.util.Objects;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Film implements Serializable{

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String naam;
    
    private String[] regisseurs;
    
    private Map<String, Integer> ratings;
    
    private int totaleRating;
    
    private String code;
    
    public Film(String naam, String[] regisseurs, Map<String, Integer> ratings, String code) {
        this.naam = naam;
        this.regisseurs = regisseurs;
        this.ratings = ratings;
        this.totaleRating = 0;
        this.code = code;
    }
    
    protected Film() {
        
    }

    @Override
    public int hashCode() {
        return Objects.hash(naam);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Film other = (Film) obj;
        return Objects.equals(naam, other.naam);
    }

    public String getNaam() {
        return naam;
    }

    public void setName(String naam) {
        this.naam = naam;
    }
    
    public Map<String, Integer> getRatings() {
        return ratings;
    }
    
    public String[] getRegisseurs() {
        return regisseurs;
    }
    
    public void addRatings(String user, int rating) {
        this.ratings.put(user, rating);
    }
    
    public Integer returnTotaleRating() {
        int sum = 0;
        if (ratings != null) {
            if (!ratings.isEmpty()) {
                sum = ratings.values().stream().mapToInt(Integer::intValue).sum();
            }
        }
        return sum;
    }

    public void setRegisseurs(String[] regisseurs) {
        this.regisseurs = regisseurs;       
    }
    
    
    public int getTotaleRating() {
        return returnTotaleRating();
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
}

FilmDao

package service;

import java.util.List;

import domain.Film;

public interface FilmDao {

    public List<Film> findAll();
}

JpaFilmDao

package service;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import domain.Film;

@Repository("filmDao")
public class JpaFilmDao implements FilmDao{

    @PersistenceContext
    private EntityManager em;
    
    @Override
    @Transactional(readOnly=true)
    public List<Film> findAll() {
        TypedQuery<Film> query = em.createQuery(
        "SELECT f FROM Film f ORDER BY f.id", Film.class);
        return query.getResultList();
    }
}

PersistenceJPAConfig

package com.springBoot.Filmfestival_JPA;

import java.util.Properties;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;


@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig {

    @Bean
       public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
          LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
          em.setDataSource(dataSource());
          em.setPackagesToScan(new String[] { "domain" });//hier moet hij kijken

          JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
          em.setJpaVendorAdapter(vendorAdapter);
          em.setJpaProperties(additionalProperties());

          return em;
       }

       @Bean
       public DataSource dataSource(){
          DriverManagerDataSource dataSource = new DriverManagerDataSource();
          dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");

          dataSource.setUrl("jdbc:mysql://localhost:3306/filmfestival?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC");
          dataSource.setUsername( "root" );
          dataSource.setPassword( "root" );
          return dataSource;
       }

       @Bean
       public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
          JpaTransactionManager transactionManager = new JpaTransactionManager();
          transactionManager.setEntityManagerFactory(emf);
          return transactionManager;
       }

       @Bean
       public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
          return new PersistenceExceptionTranslationPostProcessor();
       }

       Properties additionalProperties() {
          Properties properties = new Properties();
          properties.setProperty("hibernate.hbm2ddl.auto", "create");
          //properties.setProperty("hibernate.hbm2ddl.auto", "validate");
          return properties;
       }
}

Error:

2022-08-16 09:17:46.463  INFO 13368 --- [           main] s.F.SpringBootFilmfestivalJpaApplication : Starting SpringBootFilmfestivalJpaApplication using Java 17.0.1 on LAPTOP-REPTMNPV with PID 13368 (C:\Users\Gebruiker\Documents\workspace3-spring\Spring_Boot_Filmfestival-JPA\target\classes started by Gebruiker in C:\Users\Gebruiker\Documents\workspace3-spring\Spring_Boot_Filmfestival-JPA)
2022-08-16 09:17:46.465  INFO 13368 --- [           main] s.F.SpringBootFilmfestivalJpaApplication : No active profile set, falling back to 1 default profile: "default"
2022-08-16 09:17:46.864  INFO 13368 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2022-08-16 09:17:46.875  INFO 13368 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 JPA repository interfaces.
2022-08-16 09:17:47.008  INFO 13368 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'persistenceJPAConfig' of type [com.springBoot.Filmfestival_JPA.PersistenceJPAConfig$$EnhancerBySpringCGLIB$$624e4fe] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2022-08-16 09:17:47.044  INFO 13368 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.ws.config.annotation.DelegatingWsConfiguration' of type [org.springframework.ws.config.annotation.DelegatingWsConfiguration$$EnhancerBySpringCGLIB$$736b0246] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2022-08-16 09:17:47.079  INFO 13368 --- [           main] .w.s.a.s.AnnotationActionEndpointMapping : Supporting [WS-Addressing August 2004, WS-Addressing 1.0]
2022-08-16 09:17:47.294  INFO 13368 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2022-08-16 09:17:47.300  INFO 13368 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2022-08-16 09:17:47.300  INFO 13368 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.65]
2022-08-16 09:17:47.500  INFO 13368 --- [           main] org.apache.jasper.servlet.TldScanner     : At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
2022-08-16 09:17:47.510  INFO 13368 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2022-08-16 09:17:47.510  INFO 13368 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1018 ms
2022-08-16 09:17:47.575  INFO 13368 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
2022-08-16 09:17:47.599  INFO 13368 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 5.6.9.Final
2022-08-16 09:17:47.694  INFO 13368 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2022-08-16 09:17:47.982  INFO 13368 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect
2022-08-16 09:17:48.133 ERROR 13368 --- [           main] j.LocalContainerEntityManagerFactoryBean : Failed to initialize JPA EntityManagerFactory: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.Map, at table: Film, for columns: [org.hibernate.mapping.Column(ratings)]
2022-08-16 09:17:48.134  WARN 13368 --- [           main] 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 [com/springBoot/Filmfestival_JPA/PersistenceJPAConfig.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: java.util.Map, at table: Film, for columns: [org.hibernate.mapping.Column(ratings)]
2022-08-16 09:17:48.135  INFO 13368 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2022-08-16 09:17:48.142  INFO 13368 --- [           main] ConditionEvaluationReportLoggingListener : 


Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-08-16 09:17:48.154 ERROR 13368 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [com/springBoot/Filmfestival_JPA/PersistenceJPAConfig.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: java.util.Map, at table: Film, for columns: [org.hibernate.mapping.Column(ratings)]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) ~[spring-beans-5.3.22.jar:5.3.22]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ~[spring-beans-5.3.22.jar:5.3.22]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.22.jar:5.3.22]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.22.jar:5.3.22]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.22.jar:5.3.22]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.22.jar:5.3.22]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.22.jar:5.3.22]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154) ~[spring-context-5.3.22.jar:5.3.22]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908) ~[spring-context-5.3.22.jar:5.3.22]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.22.jar:5.3.22]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.2.jar:2.7.2]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[spring-boot-2.7.2.jar:2.7.2]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.2.jar:2.7.2]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.2.jar:2.7.2]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-2.7.2.jar:2.7.2]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-2.7.2.jar:2.7.2]
    at com.springBoot.Filmfestival_JPA.SpringBootFilmfestivalJpaApplication.main(SpringBootFilmfestivalJpaApplication.java:20) ~[classes/:na]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.Map, at table: Film, for columns: [org.hibernate.mapping.Column(ratings)]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421) ~[spring-orm-5.3.22.jar:5.3.22]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-5.3.22.jar:5.3.22]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.3.22.jar:5.3.22]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) ~[spring-beans-5.3.22.jar:5.3.22]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ~[spring-beans-5.3.22.jar:5.3.22]
    ... 16 common frames omitted
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.Map, at table: Film, for columns: [org.hibernate.mapping.Column(ratings)]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:515) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:482) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
    at org.hibernate.mapping.Property.isValid(Property.java:231) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:627) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
    at org.hibernate.mapping.RootClass.validate(RootClass.java:267) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
    at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:359) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:314) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1498) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.3.22.jar:5.3.22]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.3.22.jar:5.3.22]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-5.3.22.jar:5.3.22]
    ... 20 common frames omitted


  • Does this answer your question? [JPA Map mapping](https://stackoverflow.com/questions/853076/jpa-mapstring-string-mapping) – Federico klez Culloca Aug 16 '22 at 07:36
  • Or this? [Could not determine type for: java.util.List, at table: College](https://stackoverflow.com/a/3774245/507738) – MC Emperor Aug 16 '22 at 07:37
  • PS: `regisseurs` is a string array, but I suggest you use a `List` instead, as it's more flexible. – MC Emperor Aug 16 '22 at 07:38
  • Your error is self-explanatory. The type Map is a collection in Java and is not mapped to a specific data type in the database. Consider changing your map into an entity consisting of a an id and a list, then you can persist the list with the id and retrieve it using a Map – Pawan.Java Aug 16 '22 at 07:43
  • I suggest you to read [this](https://vladmihalcea.com/the-best-way-to-map-a-onetomany-association-with-jpa-and-hibernate/) to understand saving collections in the database – Pawan.Java Aug 16 '22 at 07:46
  • how do I need to name the JoinColumn? I keep following error "The value for annotation attribute JoinTable.joinColumns must be some @javax.persistence.JoinColumn annotation " – Seppe Everaet Aug 16 '22 at 07:46
  • @SeppeEveraet where and how are you using `JoinColumn`? – Federico klez Culloca Aug 16 '22 at 08:01
  • 1
    @Pawan.Java thanks for the advice, I made a List of Score elements (Score had a String user and int rating) instead of the map and now it works. – Seppe Everaet Aug 16 '22 at 08:55
  • @MCEmperor Yeah I know but after the creation of a movie, the movies can't be changed afterwards so that is why I didn't bother changing that to a List – Seppe Everaet Aug 16 '22 at 08:56
  • @SeppeEveraet Well, if the movies shouldn't be changed, then you *should* be using a `List` rather than an array. While the size of an array cannot change, all elements are publicly accessible, and worse, rewritable. For instance, `regisseurs[0] = "Seppe Everaet"` is always possible (for arrays with size > 0), whereas `List` implementations can control whenever it's possible to change the list. – MC Emperor Aug 16 '22 at 09:39

0 Answers0