Could not determine recommended JdbcType for <class>
Asked Answered
S

10

18

I've been searching around and potentially the closest I've found something is this Stack Overflow thread, but it still doesn't answer my question. Even with the latest copy of spring (as of writing) frameworks (2.7.2), and hibernate (6.1.2.Final), and hibernate-entitymanager (5.6.10.Final), I'm still having troubles. My full error stack is as follows:

INFO <PID> --- [main] com.lms.controller.SpringBootController  : Starting SpringBootController using Java 17.0.4 on <OS> with PID <PID> <FILEPATH> started by <USER> in <FILEPATH>)
INFO <PID> --- [main] com.lms.controller.SpringBootController  : No active profile set, falling back to 1 default profile: "default"
INFO <PID> --- [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
INFO <PID> --- [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 28 ms. Found 2 JPA repository interfaces.
INFO <PID> --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
INFO <PID> --- [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
INFO <PID> --- [main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/10.0.22]
INFO <PID> --- [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
INFO <PID> --- [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 944 ms
INFO <PID> --- [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
INFO <PID> --- [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.1.2.Final
WARN <PID> --- [main] org.hibernate.orm.deprecation            : HHH90000021: Encountered deprecated setting [javax.persistence.sharedCache.mode], use [jakarta.persistence.sharedCache.mode] instead
INFO <PID> --- [main] SQL dialect                              : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
ERROR <PID> --- [main] j.LocalContainerEntityManagerFactoryBean : Failed to initialize JPA EntityManagerFactory: Could not determine recommended JdbcType for `com.lms.entity.Role`
WARN <PID> --- [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 [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Could not determine recommended JdbcType for `com.lms.entity.Role`
INFO <PID> --- [main] com.lms.controller.SpringBootController  : Starting SpringBootController using Java 17.0.4 on <OS> with PID <PID> <FILEPATH> started by <USER> in <FILEPATH>)
INFO <PID> --- [main] com.lms.controller.SpringBootController  : No active profile set, falling back to 1 default profile: "default"
INFO <PID> --- [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
INFO <PID> --- [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 28 ms. Found 2 JPA repository interfaces.
INFO <PID> --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
INFO <PID> --- [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
INFO <PID> --- [main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/10.0.22]
INFO <PID> --- [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
INFO <PID> --- [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 944 ms
INFO <PID> --- [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
INFO <PID> --- [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.1.2.Final
WARN <PID> --- [main] org.hibernate.orm.deprecation            : HHH90000021: Encountered deprecated setting [javax.persistence.sharedCache.mode], use [jakarta.persistence.sharedCache.mode] instead
INFO <PID> --- [main] SQL dialect                              : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
ERROR <PID> --- [main] j.LocalContainerEntityManagerFactoryBean : Failed to initialize JPA EntityManagerFactory: Could not determine recommended JdbcType for `com.lms.entity.Role`
WARN <PID> --- [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 [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Could not determine recommended JdbcType for `com.lms.entity.Role`
INFO <PID> --- [main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
INFO <PID> --- [main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
  ERROR <PID> --- [main] 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]: Could not determine recommended JdbcType for `com.lms.entity.Role`
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1753) ~[spring-beans-6.0.0-M5.jar:6.0.0-M5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:604) ~[spring-beans-6.0.0-M5.jar:6.0.0-M5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:526) ~[spring-beans-6.0.0-M5.jar:6.0.0-M5]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.0-M5.jar:6.0.0-M5]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.0-M5.jar:6.0.0-M5]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.0-M5.jar:6.0.0-M5]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.0-M5.jar:6.0.0-M5]
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1141) ~[spring-context-6.0.0-M5.jar:6.0.0-M5]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:916) ~[spring-context-6.0.0-M5.jar:6.0.0-M5]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:592) ~[spring-context-6.0.0-M5.jar:6.0.0-M5]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.0.0-M4.jar:3.0.0-M4]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) ~[spring-boot-3.0.0-M4.jar:3.0.0-M4]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:430) ~[spring-boot-3.0.0-M4.jar:3.0.0-M4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) ~[spring-boot-3.0.0-M4.jar:3.0.0-M4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) ~[spring-boot-3.0.0-M4.jar:3.0.0-M4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) ~[spring-boot-3.0.0-M4.jar:3.0.0-M4]
        at com.lms.controller.SpringBootController.main(SpringBootController.java:30) ~[classes/:na]
Caused by: org.hibernate.type.descriptor.java.spi.JdbcTypeRecommendationException: Could not determine recommended JdbcType for `com.lms.entity.Role`
        at org.hibernate.type.descriptor.java.spi.UnknownBasicJavaType.getRecommendedJdbcType(UnknownBasicJavaType.java:37) ~[hibernate-core-6.1.2.Final.jar:6.1.2.Final]
        at org.hibernate.type.descriptor.java.spi.BasicCollectionJavaType.getRecommendedJdbcType(BasicCollectionJavaType.java:70) ~[hibernate-core-6.1.2.Final.jar:6.1.2.Final]
        at org.hibernate.boot.model.process.internal.InferredBasicValueResolver.from(InferredBasicValueResolver.java:222) ~[hibernate-core-6.1.2.Final.jar:6.1.2.Final]
        at org.hibernate.mapping.BasicValue.buildResolution(BasicValue.java:507) ~[hibernate-core-6.1.2.Final.jar:6.1.2.Final]
        at org.hibernate.mapping.BasicValue.resolve(BasicValue.java:315) ~[hibernate-core-6.1.2.Final.jar:6.1.2.Final]
        at org.hibernate.mapping.BasicValue.resolve(BasicValue.java:305) ~[hibernate-core-6.1.2.Final.jar:6.1.2.Final]
        at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.lambda$processValueResolvers$4(InFlightMetadataCollectorImpl.java:1766) ~[hibernate-core-6.1.2.Final.jar:6.1.2.Final]
        at java.base/java.util.ArrayList.removeIf(ArrayList.java:1682) ~[na:na]
        at java.base/java.util.ArrayList.removeIf(ArrayList.java:1660) ~[na:na]
        at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processValueResolvers(InFlightMetadataCollectorImpl.java:1765) ~[hibernate-core-6.1.2.Final.jar:6.1.2.Final]
        at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1751) ~[hibernate-core-6.1.2.Final.jar:6.1.2.Final]
        at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:300) ~[hibernate-core-6.1.2.Final.jar:6.1.2.Final]
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1350) ~[hibernate-core-6.1.2.Final.jar:6.1.2.Final]
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1421) ~[hibernate-core-6.1.2.Final.jar:6.1.2.Final]
        at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-6.0.0-M5.jar:6.0.0-M5]
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:362) ~[spring-orm-6.0.0-M5.jar:6.0.0-M5]
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-6.0.0-M5.jar:6.0.0-M5]
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-6.0.0-M5.jar:6.0.0-M5]
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:338) ~[spring-orm-6.0.0-M5.jar:6.0.0-M5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1799) ~[spring-beans-6.0.0-M5.jar:6.0.0-M5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1749) ~[spring-beans-6.0.0-M5.jar:6.0.0-M5]
        ... 16 common frames omitted

Here's my Role.java file:

package com.lms.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.EnumType;

@Entity
@Table(name = "roles")
public class Role {
    @Id
    @Column(name = "roleID", nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int roleID;
    
    @Enumerated(EnumType.STRING)
    @Column(name = "roleName", nullable = false)
    private RoleEnum roleName;

    public int getRoleID(){
        return this.roleID;
    }
    public void setRoleID(int roleid){
        this.roleID = roleid;
    }
    public RoleEnum getRoleName(){
        return this.roleName;
    }
    public void setRoleName(RoleEnum rolename){
        this.roleName = rolename;
    }

    @Override
    public String toString(){
        return "The role's id is: " + this.roleID + "\nThe role's name is: " + this.roleName.toString();
    }
}

Even if my Role.java contains only the roleID value, I get the same error which isn't thrown on my other Entity classes which are basically the same thing. The only unique thing about this class is the RoleEnum type which is based on this Enum class: RoleEnum.java

public enum RoleEnum {
    SUPER_ADMIN,
    FORUM_ADMIN,
    ACCOUNTANT,
    LIBRARIAN,
    NORMAL_USER,
    FORUM_USER
}

I came across this error when I was trying to replicate this person's guide of implementing a JWT in Java Spring and works, but they are using 2.2.11.RELEASE instead of 3.0.0-M4 which is what I'm using.

My likely candidates are there is something funky with jakarta.* instead of javax.* which I don't fully understand the differences between. The other candidate I'm thinking could be problematic is that something with EntityManager is causing a problem, but I can't find anything about it. My error is Could not determine recommended JdbcType for com.lms.entity.Role, is there something I can do to fix this?

Strontianite answered 10/8, 2022 at 21:14 Comment(6)
Error likely has you looking in the wrong spots. Your entity def won’t be the problem, it will be somewhere else referencing a com.lms.entity.Role. The exception mentions a basic collection mapping, so check your other entities and class’ mappingsCherellecheremis
Hibernate 6.1 doesn't work with Spring Boot 2.7. Imho you are managing too much, you probably have Spring Data Jpa as a dependency (which already pulls in hibernate). Remove your explicit management for the hibernate dependencies.Preach
@Chris: That was another thought of mine because I literally copied and pasted another entity in this class file and it wasn't working either. I tried looking around to other class mappings but didn't see anything wrong with it.Strontianite
@M.Deinum: You're right that I did have Spring Data JPA as a dependency. I didn't know it pulled in hibernate, so thank you. I removed the hibernate dependency and receive the error of "A component required a bean named 'entityManagerFactory' that could not be found."Strontianite
That would be strange, could you ask that in a new question and provide the stacktrace as well as a list of your dependencies (i.e. add your pom.xml).Preach
Sorry, I was on vacation @M.Deinum. What I ended up doing was refactor my code and commented my RoleEnum class out. I had previously a class within a public class within my other public class for the filterChain that I since refactored to not be a subclass (again inexperience with Spring, this is why I'm learning!) When I did some other refactors, I uncommented the RoleEnum and RoleRepository classes and the error was not thrown. Unfortunately, I won't be able to recreate the error. If I do run across it, I will make sure to create a new post! Thanks for y'all's help!Strontianite
M
13

I had the same problem, I solve it by adding the @ManyToOne annotation. I guess in your case it would be in the RoleEnum field. Well at least that's how it worked for me.

Muricate answered 15/12, 2022 at 3:12 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Cordula
B
11

Adding implements Serializable on the entity class solves the problem.

@Entity
public class Employee implements Serializable {

Entity classes must be Serializable so they can be serialized and peristed into or read out of the database files.

Benighted answered 11/2 at 19:58 Comment(1)
This was the right fix in my case (thanks!) If you're defining a property with a value that needs a @Convert annotation, make sure that value class is Serializable and also it should override equals() and hashCode().Frech
C
6

I had a similar error. Not really a dependency issue.

org.hibernate.type.descriptor.java.spi.JdbcTypeRecommendationException: Could not determine recommended JdbcType for com.payment.Payment

In my case, I found that Payment entity has a relationship with other entities, and was in fact used elsewhere.

The Error was fixed by removing this instances of the entity used in other entities, hence not "confusing" Hibernate on how to create Payment entity.

Cyclostyle answered 7/11, 2022 at 11:19 Comment(0)
F
4

This error has many causes, but in your case seems to be a relation between Role entity and another one that is using it in a relation. The most common reason for this error is reference this entity in another, and do not set the proper annotations.

In my case, I had the entity MealFood (which the error log was pointing to), and it was used in Meal entity. (One to Many starting from MealFood). The problem was that I hadn't mapped it properly in the Meal entity, so hibernate didn't know exactly what to do with it.

Please check if, as mentioned in jayson mulwa answer, the Role entity is used in another class, and add the proper annotations.

Hope it helps.

Fighter answered 10/12, 2022 at 16:19 Comment(3)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Cordula
yeah but what annotations do you mean?????-Bremsstrahlung
@Bremsstrahlung if, in my example, the Meal entity is referencing another entity (MealFood), this reference should contain the annotations to determine the relation of this two entities. So in my scenario, if Meal reference MealFood, it should contain @ManyToOne annotation.Fighter
O
2

I struggled with this for a very long time and couldn't find a solution anywhere. I found the cause which was in a different entity where I was calling the entity mentioned in the error message with @ManyToOne (for me it was the user entity, it seems like for OP it was roles). The error only went away once I added @JdbcTypeCode(SqlTypes.JSON) where it was called, so it looked like this:

@JdbcTypeCode(SqlTypes.JSON)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "SUBMITTED_BY")
private User user;

I ofc also had to import:

import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;

I don't know if this fix just causes another problem down the line or I'm missing something else cus I can't even find where I got the original solution but fingers crossed it's fine.

Osmo answered 11/4, 2023 at 22:48 Comment(0)
H
1

Although brief the solution proposed by Gustavo Junkes and the explanation of Paimon helped me with a similar case I have during a migration from javax.persistence to jakarta.persistence. Here is how I solved a similar issue in order to make work a @OnetoMany relation between 2 entities:

I had to add a @ManyToOne relation on the child entity (ITEM). I insist that it wasn't necessary before with javax.persitence (although the cause may be something else as other dependencies have been changed). Anyway, before it worked fine without that. So here is what I have now which works: In the Item entity (child):

@Column(name = "BRAND_ID", nullable = false, insertable = false, updatable = false)
private long brandId;

@JoinColumn(name = "BRAND_ID", nullable = false)
@ManyToOne(targetEntity=Brand.class, fetch=FetchType.LAZY)
private Brand brand;

In the Brand entity (parent):

   @Column(name="BRAND_ID")
   private long id;

   @OneToMany(targetEntity= Item.class, cascade=ALL, mappedBy="brand", fetch=FetchType.LAZY)
   private List<Item> items = new ArrayList<>();

Notice that before the migration to jakarta.persistence the @OneToMany annotation referred to the "brandId" property in the child entity. Now it refers to the new "brand" property in the child entity. Here is how it was before. Moreover there was no need to specify the @ManyToOne annotation in the child entity:

@OneToMany(targetEntity=Item.class, cascade=ALL, mappedBy="brandId", fetch=FetchType.LAZY)
private List<Item> items = new ArrayList<>();
Hitchhike answered 23/9, 2023 at 12:12 Comment(0)
M
0

In my case I missed an @Id on a related @ManyToOne class. The class mentioned in the error was ok.

The @Id goes on the getter, not on the field, although it's allowed.

Migrant answered 23/11, 2023 at 13:26 Comment(0)
S
0

I had similar error,

[org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Could not determine recommended JdbcType for Java type 'com.scaler.bookmyshow.Models.SeatType'

i missed to specify relationship for one of the attribute in model class (@ManyToOne) after adding this annotation error is gone.

Simplism answered 7/6 at 7:55 Comment(0)
P
0

I had the same Issue, with the help of this comment: https://mcmap.net/q/655839/-could-not-determine-recommended-jdbctype-for-lt-class-gt

I went back and checked my annotations , it turned out that I had improperly annotated one of the entities, I had put the annotations on the getter instead.

Before:

private List<Speaker> speakers;
public Session(){

}

@ManyToMany
@JoinTable(name="session_speakers",joinColumns =@JoinColumn(name="session_id"),inverseJoinColumns = @JoinColumn(name="speaker_id"))

public List<Speaker> getSpeakers() {
    return speakers;
}

After

@ManyToMany
@JoinTable(name="session_speakers",joinColumns =@JoinColumn(name="session_id"),inverseJoinColumns = @JoinColumn(name="speaker_id"))

private List<Speaker> speakers;
public Session(){

}

public List<Speaker> getSpeakers() {
    return speakers;
}
Pilgrim answered 17/7 at 16:4 Comment(0)
C
-1

This is because you change is remain in hibernate.cfg.xml - please check your hibernate.cfg.xml file you made some changes - so correct it in my problem i change the class name by mistake

Cafeteria answered 6/4, 2023 at 9:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.