4

I have a user entity:

User.java

@Entity
public class user {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@NotNull
@NotBlank
private String firstname;
...

When I am deploying the application the first time it will create this table in my database.

My question: is there any way to create an admin user with firstname together with the table user when it gets created?

anothernode
  • 5,100
  • 13
  • 43
  • 62
Yagami Light
  • 1,756
  • 4
  • 19
  • 39

2 Answers2

8

i prefer always to avoid sql script so i use CommandLineRunner interface. this is an example using spring data, its not a working code :

@Component    
public class CommandLineAppStartupRunner implements CommandLineRunner {
    @Autowired
    UserRepository userRepository;

    @Override
    public void run(String...args) throws Exception {
        User admin = new user(firstName);
        userRepository.save(admin);
    }
}

before the app starts this class will be executed.

Issam EL-GUERCH
  • 408
  • 3
  • 8
  • And try to create /merge again at every startup, sounds wrong to be. – Deividi Cavarzan Sep 18 '18 at 02:29
  • Yeah it's sound wrong cause you need to call create/merge each time (it's an extra call that we don't need) your solution work but there is a better one +1 for the answer – Yagami Light Sep 18 '18 at 07:19
  • 1
    This approach is better than plain SQL script because script is not aware about your db schema changes and need to be changed manually. Using entities you will be able to track errors at compiler time. – chill appreciator Jul 28 '20 at 23:18
  • Yeah, I agree, this is better than using an SQL script – anothernode Apr 19 '21 at 13:43
2

This answer actually shows a better approach and should be the accepted one.


You can put something like this in src/main/resources/data.sql:

INSERT INTO users (firstname, password, enabled)
SELECT 'admin', 'secret', TRUE
WHERE NOT EXISTS (SELECT * FROM users WHERE firstname='admin');

Assuming you are using PostgreSQL for the database backend.

As I don't know the database schema you are using, you'll have to modify this query to match your schema, but it should give you the basic idea.

I think you don't even need to add any configuration for this to work as Spring will pick it up automatically and use it for database initialization if it's in the right directory.

According to another answer to a similar question, in Spring Boot 2.x you'll have to add the following piece of configuration for this to work:

spring.datasource.initialization-mode=always
anothernode
  • 5,100
  • 13
  • 43
  • 62
  • 2
    If the password is encrypted or salted and the hashing logic is in the Java app, this approach becomes a bit awkward because the password value to insert is not known. Any way to work around this? – wlnirvana Apr 17 '21 at 13:55