简体   繁体   中英

Spring Boot JPA initialize data - Syntax error in SQL statement ... expected "identifier"

Try to implement data into my Spring Boot application at the start up. As I researched it should be working like this:

user_role class:

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class UserRole {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String role;
}

schema.sql

CREATE TABLE `user_role` (
    `id` bigint(20) NOT NULL,
    `role` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 

data.sql

INSERT INTO user_role (role) VALUES ('ADMIN');
INSERT INTO user_role (role) VALUES ('USER');

application.properties

spring.jpa.hibernate.ddl-auto=none
spring.jpa.defer-datasource-initialization=true
spring.sql.init.mode=always

But if I try this I only got the following error when I am building the application:

Syntax error in SQL statement "CREATE TABLE USER_ROLE ( ID BIGINT([*]20) NOT NULL, ROLE VARCHAR(255) DEFAULT NULL, PRIMARY KEY ( ID ) ) ENGINE=INNODB DEFAULT CHARSET=UTF8MB4"; expected "ARRAY, INVISIBLE, VISIBLE, NOT, NULL, AS, DEFAULT, GENERATED, ON, NOT, NULL, AUTO_INCREMENT, DEFAULT, NULL_TO_DEFAULT, SEQUENCE, SELECTIVITY, COMMENT, CONSTRAINT, COMMENT, PRIMARY, UNIQUE, NOT, NULL, CHECK, REFERENCES, AUTO_INCREMENT, ., )"; SQL statement: CREATE TABLE user_role ( id bigint(20) NOT NULL, role varchar(255) DEFAULT NULL, PRIMARY KEY ( id ) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 [42001-202]

Does someone know what is wrong?

If you created the user_role table with your script then the problem is the id column definition where the AUTO_INCREMENT is missing from it. Because you want to insert fields without manually adding the id values. So the correct sql code for the table creation should be:

CREATE TABLE `user_role` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT,
    `role` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 

In this case the insert sql code will work fine.

But you should generate a table with spring and insert data with a repository!

Repository for UserRole entity:

public interface UserRoleRepository extends CrudRepository<UserRole, Long> {}

After that just call the save method with the new instance of the entity in your service:

@AllArgsConstructor
@Service
public class YourService {

    private final UserRoleRepository userRoleRepository;

    public void exampleMethod() {
        final UserRole role = new UserRole();
        role.set("ADMIN");
        userRoleRepository.save(role);
    }
}

Last thing: dou you relly want to create table for roles? I mean if users can create other roles then okay but if the roles are fix would be better just add role field to the user where the field type is enum which contains the user roles.

public enum UserRole {
    ADMIN,
    USER
}

User entity with role field:

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @Enumerated(EnumType.STRING)
    private UserRole role;
}

Exception specifies that some problem with your SQL.

You have to specify that id should be incremented:

CREATE TABLE IF NOT EXISTS opening_hour
(
    id    INT AUTO_INCREMENT PRIMARY KEY,
    role  VARCHAR(50)  null
);

Because later when the data is inserted, like:

INSERT INTO user_role (role) VALUES ('ADMIN');

You don't set id directly it should be auto-incremented by the DB engine.

Also, JPA API requires that your entities have to be serializable. You have to update it like following:

public class UserRole implements Serializable {
    private static final long serialVersionUID = 1L;

Probably for your purpose you select the easiest way to do this.

Much harder will be to use some migration applications like Flyway or Liquiebase and create some init script for this purpose.

However, in this case, your DB interactions (like adding a new field to a class, thus updating the DB table respectively) should do it through adding a new migration script.

Write it here, because it is too long to write it like a comment under the post.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM