Skip to content
Advertisement

CrudRepository doesn’t save data

I’m having trouble while saving new object into database via CrudRepository. Interesting thing is that I can read data from repository.

So, while I’m getting data, I have an SQL query in console. While I’m saving data, console is empty. Moreover, CrudRepository.save returns a valid object, with assigned id.

Could you please take a look? Thanks you in advance.

controller class:

@Controller
public class UserController {
    @Autowired
    private UserRepository userRepository;

    @GetMapping(value = "/users", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Iterable<User>> viewUsers() {
        return ResponseEntity.ok(userRepository.findAll());
    }

    @PutMapping(value = "/users/add", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<String> addUser(@RequestBody User user) {
        User persisted = userRepository.save(user);
        System.out.println(persisted);
        if (persisted == null) {
            return new ResponseEntity<>("Error while saving user", HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new ResponseEntity<>("OK", HttpStatus.CREATED);
    }
}

entity class:

@Entity
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(generator = "system-uuid2")
    @GenericGenerator(name = "system-uuid2", strategy = "uuid2")
    private String id;
    @Column(name = "first_name")
    private String firstName;
    @Column(name = "last_name")
    private String lastName;
    @Column(name = "email")
    private String email;
    @Column(name = "password")
    private String password;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("User{");
        sb.append("id='").append(id).append(''');
        sb.append(", firstName='").append(firstName).append(''');
        sb.append(", lastName='").append(lastName).append(''');
        sb.append(", email='").append(email).append(''');
        sb.append(", password='").append(password).append(''');
        sb.append('}');
        return sb.toString();
    }
}

sql where table is created:

CREATE TABLE USER(
    ID VARCHAR(255) NOT NULL UNIQUE,
    FIRST_NAME VARCHAR(255) NOT NULL,
    LAST_NAME VARCHAR(255) NOT NULL,
    EMAIL VARCHAR(255) NOT NULL,
    PASSWORD VARCHAR(255) NOT NULL,
    PRIMARY KEY (ID)
);

and java-based configuration:

@Configuration
@EnableJpaRepositories(basePackages = "ua.maximenko.jquizful.repository")
@EnableTransactionManagement
@EnableWebMvc
public class Config implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.indentOutput(true).simpleDateFormat("yyyy-MM-dd HH:mm:ss");
        converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
    }

    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

    @Bean
    public DataSource dataSource() {
        EmbeddedDatabaseBuilder dbBuilder = new EmbeddedDatabaseBuilder();
        return dbBuilder
                .setType(EmbeddedDatabaseType.H2)
                .addScript("classpath:sql/create-tables.sql")
                .addScript("classpath:sql/populate-tables.sql")
                .build();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        adapter.setShowSql(true);
        LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
        factoryBean.setJpaVendorAdapter(adapter);
        factoryBean.setDataSource(dataSource());
        return factoryBean;
    }

    @Bean
    public JpaTransactionManager transactionManager() {
        JpaTransactionManager tm = new JpaTransactionManager();
        tm.setEntityManagerFactory(entityManagerFactory().getNativeEntityManagerFactory());
        return tm;
    }
}

User repository:

package ua.maximenko.jquizful.repository;

import org.springframework.data.repository.CrudRepository;
import ua.maximenko.jquizful.domain.User;

public interface UserRepository extends CrudRepository<User, String> {
}

Also screen with project structure is attachedProject structure

Please let me know if any additional info is required.

Answer

I think this config is wrong:

@Bean
public JpaTransactionManager transactionManager() {
    JpaTransactionManager tm = new JpaTransactionManager();
    tm.setEntityManagerFactory(entityManagerFactory().getNativeEntityManagerFactory());
    return tm;
}

You must call getObject() on the EntityManagerFactory:

@Bean
public JpaTransactionManager transactionManager() {
    JpaTransactionManager tm = new JpaTransactionManager();
    tm.setEntityManagerFactory(entityManagerFactory().getObject());
    return tm;
}
Advertisement