Home > Back-end >  Why I fail to use properties from application.properties file in Spring Boot?
Why I fail to use properties from application.properties file in Spring Boot?

Time:11-14

Why I fail to use data from application.properties in the PostDao class? Properties just not injected and DATABASE_URL and other variables are null.
PostDao.java is the class (src.main.java.site.model.PostDao) where I try to use properties.

@Component
public class PostDao
{
    @Value("${url}") public static String DATABASE_URL;
    @Value("${user}") public static String USER;
    @Value("${password}") public static String PASSWORD;
}

Here is my application.peoprerties file which stays in the resources directory

url=jdbc:postgresql://localhost:5432/news
user=postgres
password=123

Here is my config file (src.main.java.site.NewsSiteApplication)

@SpringBootApplication
public class NewsSiteApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(NewsSiteApplication.class, args);
    }
}

CodePudding user response:

You can't inject in a static variable. You need a Spring-managed Bean for that. Try the following:

@Component
public class PostDao {
    @Value("${url}") public String databaseUrl;
    @Value("${user}") public String user;
    @Value("${password}") public String password;
}

As pointed out by @Turing85 (thanks for the hint ;) ), only constants should be written in UPPER_SNAKE_CASE, hence I changed the variables name.


My suggestions in regards to your code that is currently based on static methods, when it shouldn't as explained in my comment.

@Component
public class PostDao implements ApplicationListener<ContextRefreshedEvent> {
    @Value("${url}")
    private String databaseUrl;

    @Value("${user}")
    private String user;

    @Value("${password}")
    private String password;

    private Connection connection;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        try {
            connection = DriverManager.getConnection(databaseUrl, user, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public ArrayList<Post> getAllPosts()
    {
        ArrayList<Post> posts = new ArrayList<>();

        String sqlQuery = "SELECT * FROM news ORDER BY id;";
        try (Statement statement = connection.createStatement(); 
             ResultSet resultSet = statement.executeQuery(sqlQuery)
        )
        {
            while (resultSet.next())
            {
                int id = resultSet.getInt("id");
                String header = resultSet.getString("header");
                String image_filename = resultSet.getString("image_filename");
                String text = resultSet.getString("text");
                java.util.Date creationDate = resultSet.getDate("creation_date");

                posts.add(new Post(id, header, image_filename, text, creationDate));
            }
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }

        return posts;
    }

    public void addPost(String header, String imageFileName, String text, Date creationDate)
    {
        String sqlQuery = "INSERT INTO news VALUES (DEFAULT, ?, ?, ?, ?);";

        try (PreparedStatement preparedStatement = connection.prepareStatement(sqlQuery))
        {
            preparedStatement.setString(1, header);
            preparedStatement.setString(2, imageFileName);
            preparedStatement.setString(3, text);
            preparedStatement.setDate(4, new java.sql.Date(creationDate.getTime()));

            preparedStatement.executeUpdate();
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
    }

    public void deletePost(int postId)
    {
        String sqlQuery = "DELETE FROM news WHERE id = ?;";

        try (PreparedStatement preparedStatement = connection.prepareStatement(sqlQuery))
        {
            preparedStatement.setInt(1, postId);

            preparedStatement.executeUpdate();
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
    }

    public void updateHeader(String header, int postId)
    {
        String sqlQuery = "UPDATE news SET header = ? WHERE id = ?;";

        try (PreparedStatement preparedStatement = connection.prepareStatement(sqlQuery))
        {
            preparedStatement.setString(1, header);
            preparedStatement.setInt(2, postId);

            preparedStatement.executeUpdate();
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
    }

    public void updateText(String text, int postId)
    {
        String sqlQuery = "UPDATE news SET text = ? WHERE id = ?;";

        try (PreparedStatement preparedStatement = connection.prepareStatement(sqlQuery))
        {
            preparedStatement.setString(1, text);
            preparedStatement.setInt(2, postId);

            preparedStatement.executeUpdate();
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
    }

    public void updateImageName(String imageFilename, int postId)
    {
        String sqlQuery = "UPDATE news SET image_filename = ? WHERE id = ?;";

        try (PreparedStatement preparedStatement = connection.prepareStatement(sqlQuery))
        {
            preparedStatement.setString(1, imageFilename);
            preparedStatement.setInt(2, postId);

            preparedStatement.executeUpdate();
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
    }

    public void updateDate(java.util.Date date, int postId)
    {
        String sqlQuery = "UPDATE news SET creation_date = ? WHERE id = ?;";

        try (PreparedStatement preparedStatement = connection.prepareStatement(sqlQuery))
        {
            preparedStatement.setDate(1, new java.sql.Date(date.getTime()));
            preparedStatement.setInt(2, postId);

            preparedStatement.executeUpdate();
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
    }
}

Now you need to inject the PostDao bean in your PostsController as follows:

@Controller
public class PostsController
{

    private PostDao postDao;

    public PostsController(PostDao postDao) {  // This instructs Spring to inject a PostDao bean
        this.postDao = postDao;
    }

    @GetMapping("/posts")
    public String showPosts(HttpServletRequest request, Model model, @RequestParam(value = "modify", required = false) boolean modify)
    {
        if (modify && request.isUserInRole("ADMIN"))
        {
            model.addAttribute("modify", true);
        }
        
        // truncate text to 150 characters and add " ..."
        ArrayList<Post> posts = postDao.getAllPosts();
        for (Post post : posts)
        {
            String text = post.getText();
            if (text.length() > 150)
            {
                text = text.substring(0, 151);
                text = text.trim().concat(" ...");
            }
            post.setText(text);
        }
        
        model.addAttribute("posts", posts);
        return "posts";
    }
    
    @GetMapping("/posts/{id}")
    public String showPostById(Model model, @PathVariable("id") int id)
    {
        model.addAttribute("post", postDao.getAllPosts().get(id - 1));
        return "post";
    }
}

CodePudding user response:

Alternatively, you can do the following, the setter method will handle for the injection:

@Component
public class PostDao
{
    public static String DATABASE_URL;


    @Value("${url}")
    public void setUrlStatic(String name){
        PostDao.DATABASE_URL = name;
    }

    // And others..
}
  • Related