1

My App in SpringBoot can not run properly. Tried to change dependencies, classpath, deleting and reinstall whole folder with hibernate in local .m2. I'm making Spring boot security login system in my app, before that, everything was alright.

change dependencies, classpath, deleting and reinstall whole folder with hibernate in local .m2

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</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>

        <!--SWAGGER  -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.0.16.Final</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.4.4.Final</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.4.4.Final</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.1-api</artifactId>
            <version>1.0.2.Final</version>
        </dependency>

        <!--LOMBOK -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--SPRINGBOOT -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>2.1.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
        <!--SPRING SECURITY -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>


        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.0</version>
        </dependency>

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 java.lang.ClassCastException: class org.hibernate.mapping.SingleTableSubclass cannot be cast to class org.hibernate.mapping.RootClass (org.hibernate.mapping.SingleTableSubclass and org.hibernate.mapping.RootClass are in unnamed module of loader 'app')
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1778) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1105) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:742) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:389) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:311) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1213) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1202) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at michalwds.CosmicAppApplication.main(CosmicAppApplication.java:27) ~[classes/:na]
Caused by: java.lang.ClassCastException: class org.hibernate.mapping.SingleTableSubclass cannot be cast to class org.hibernate.mapping.RootClass (org.hibernate.mapping.SingleTableSubclass and org.hibernate.mapping.RootClass are in unnamed module of loader 'app')
    at org.hibernate.cfg.annotations.PropertyBinder.bind(PropertyBinder.java:214) ~[hibernate-core-5.4.4.Final.jar:5.4.4.Final]
    at org.hibernate.cfg.annotations.PropertyBinder.makePropertyValueAndBind(PropertyBinder.java:205) ~[hibernate-core-5.4.4.Final.jar:5.4.4.Final]
    at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:2282) ~[hibernate-core-5.4.4.Final.jar:5.4.4.Final]
    at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:975) ~[hibernate-core-5.4.4.Final.jar:5.4.4.Final]
    at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:802) ~[hibernate-core-5.4.4.Final.jar:5.4.4.Final]
    at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:254) ~[hibernate-core-5.4.4.Final.jar:5.4.4.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.processEntityHierarchies(MetadataBuildingProcess.java:230) ~[hibernate-core-5.4.4.Final.jar:5.4.4.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:273) ~[hibernate-core-5.4.4.Final.jar:5.4.4.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:900) ~[hibernate-core-5.4.4.Final.jar:5.4.4.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:931) ~[hibernate-core-5.4.4.Final.jar:5.4.4.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) ~[spring-orm-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    ... 16 common frames omitted
spring.datasource.url=jdbc:mysql://localhost:3306/cosmicdb?useSSL=false&true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false
spring.jpa.hibernate.ddl-auto=update

spring.datasource.username=${database.login}
spring.datasource.password=${database.password}

server.port=8080
@NoArgsConstructor
@AllArgsConstructor
@Data //getters and setters Lombok
@Entity
@Table(name = "role")
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "role_id")
    private int roleId;

    private String role;

    @JsonIgnore 
    @ManyToMany(mappedBy = "roles")
    private Set<UserApp> users = new HashSet<>(); 

}
@NoArgsConstructor
@Data
@Entity
@Table(name = "user")
public class UserApp  extends michalwds.commons.security.Role {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;
    private String password;
    private int active; 

    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    @JoinTable(name = "user_role",
            joinColumns =
            @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> roles;

    public UserApp(UserApp userApp) {  
        this.name = userApp.getName();
        this.password = userApp.getPassword();
        this.active = userApp.getActive();
        this.roles = userApp.getRoles();
    }

}
@PropertySource("classpath:config.properties")
@SpringBootApplication
public class CosmicAppApplication {
    public static void main(String[] args) {
        SpringApplication.run(CosmicAppApplication.class, args);
    }
public class ServletInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(CosmicAppApplication.class);
    }

}
MichalWds
  • 13
  • 7
  • How did you configure hibernate and how do you use it in your code, do you use @NaturalIdCache annotation? Could you share application.properties and java code? Without more details it will be a guessing game – Victor Kim Sep 08 '19 at 23:19
  • ok, added properties and code – MichalWds Sep 08 '19 at 23:48
  • Do you get build error or test error? I created a Spring Boot app and configured it as you described (same pom deps, same application.properties, same classes) - it builds fine for me. How did you configure Application.java? – Victor Kim Sep 09 '19 at 01:09
  • I will show you when I get home in few hours. When i did mvn install cycle, tests fails but it's also strange becuase i didn't create any tests yet, only one default. Ok,posted – MichalWds Sep 09 '19 at 07:13

3 Answers3

0

Make sure that your application.properties file has the correct database url. Also check if the entity name is the correct. That’s a common mistake creating the database connection.

Leandro Maro
  • 325
  • 1
  • 12
  • yes it's good. i made tables some time ago and it worked properly. connection with db looks fine ( i mean while testing connection, also firsts tables was created) after adding roles and some security config it stoped to work – MichalWds Sep 08 '19 at 23:33
  • Check providing the @Entity with the database and table name. For example @Entity(company.employee) – Leandro Maro Sep 09 '19 at 02:01
0

The problem is with how you have defined your entities. Both the superclass and the subclass have @Id attributes.

Inheritance should be governed by an IS-A HAS-A relationship.

Hence, the @Id in your subclass should be ruled out, because an instance of the subclass should be identifiable by the corresponding @Id of the superclass, which means the subclass must have the attribute that is supposed to be the @Id of the superclass (inheritance tree).

Furthermore, it is necessary that your superclass has an @Id, so quick solution is to get rid of the @Id in the subclass and add the same attribute in the subclass (without the @Id annotation).

/* Class level annotations */
public class Role { //Superclass
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "role_id")
    private Integer roleId;
}

/* Class level annotations */
public class UserApp  extends Role { //Subclass
    private Integer roleId; // Same as the @Id in superclass
}

For further read-up on Inheritance in Hibernate, I suggest this article

Yash
  • 11,486
  • 4
  • 19
  • 35
0

You are using inheritance for JPA entities: UserApp extends Role, but at the same time you declare that UserApp should have it's own @Id. The problem here is that you are trying to map inheritance of domain entities to a relational database. SQL doesn’t support this kind of relationship directly and Hibernate, or any other JPA implementation has to map it to a supported concept.

You can choose between 4 strategies which map the inheritance structure of your domain model to different table structures: Mapped Superclass, Table per Class, Single Table or Joined table approach. Each of these strategies has its advantages and disadvantages. And you should choose the one that fits best your use case. Please find more details here.

Meanwhile I reproduced the issue on my machine using your configuration and the code you've provided and as I mentioned, the field annotated with @Id in UserApp class is causing the problem. One of quick fix options is to remove this field in UserApp. So, following code runs the test just fine on my machine:

@NoArgsConstructor
@Data
@Entity
@Table(name = "user")
public class UserApp extends Role {

    private String name;
    private String password;
    private int active;

    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(name = "user_role",
            joinColumns =
            @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> roles;

    public UserApp(UserApp userApp) {

    }
}

And as far as you mentioned in one of comments that this error occurs in the default test (not written by you) - there is always an option to skip it, if you want just build:

mvn clean install -DskipTests
Victor Kim
  • 1,647
  • 2
  • 16
  • 33
  • When i delete pole with Id it didn't change too much. Anyway, i'm not sure if i get it right. So it's not possible to have more than one Id even in different tables? – MichalWds Sep 09 '19 at 18:53
  • You can have ids in different tables, but you also should distinguish DB tables and JPA entities. Because there is a natural objects inheritance in Java and no inheritance of tables in a Relational DB the ORM should take care of it. Actually, you should take care of it whenever inheritance is involved based on your use case and ORM (in your case Hibernate) provides tools for that (see 4 strategies posted in my answer) – Victor Kim Sep 09 '19 at 19:05
  • Thanks. I remove extends Role class from UserApp. Also remove all imports, and wrote everything from the beginning, I mean this class. It is compiling right now. I think, the problem was in imports, I took one from hibernate not javax i guess. Anyway, Those information you wrote, it helps me a lot. I'm starting understand a little bit more. I will read whole article about strategies in free time – MichalWds Sep 09 '19 at 20:18