Spring Data Jpa - Почему после вставки происходит обновление? - PullRequest
0 голосов
/ 13 апреля 2020

Hy, у меня проблема при вставке сущностей. После вставки данных всегда есть обновление. Мой вопрос заключается в том, как я могу избежать ненужного обновления. Я написал тест, но есть та же проблема.

Я использую:

  • данные весенней загрузки jpa 2.2.6.RELEASE
  • весенняя загрузка 2.2. 6.RELEASE

Кто-нибудь может мне помочь, пожалуйста?

Вот мой код моей сущности:

@MappedSuperclass
@Access(AccessType.FIELD)
public abstract class BaseEntity implements Serializable
{
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    protected BigInteger id;

    @Column(name="created_at", nullable = false)
    @Type(type = "de.orderbook.hibernate.type.LocalDateTimeUserType")
    @JsonSerialize(using = LocalDateTimeJsonSerializer.class)
    @JsonDeserialize(using = LocalDateTimeJsonDeserializer.class)
    @JsonProperty
    protected LocalDateTime createdAt = LocalDateTime.now();

    @Column(name="changed_at", nullable = false, columnDefinition = "timestamp default current_timestamp on update current_timestamp")
    @JsonProperty
    @Version
    protected java.sql.Timestamp changedAt;

    public BigInteger getId() {
        return id;
    }

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

}
@Entity
@Table(name="`orderdetail`")
@Access(AccessType.FIELD)
public class Orderdetail extends BaseEntity {
    private static final long serialVersionUID = 1L;

    private String name;

    @ManyToOne
    @JoinColumn(name = "unit_id")
    private Unit unit;

    @Embedded
    private PriceOption priceOption;

    @ManyToOne
    @BatchSize(size = 100 )
    @JoinColumn(name="user_id")
    @JsonProperty(value = "user", access = JsonProperty.Access.READ_WRITE)
    private User user;

    public Orderdetail() {
        super();
    }

    @JsonCreator
    public Orderdetail(@JsonProperty("name") String name,
                       @JsonProperty("unit") Unit unit,
                       @JsonProperty("user") User user,
                       @JsonProperty("price") PriceOption priceOption) {
        super();
        this.name = name;
        this.unit = unit;
        this.user = user;
        this.priceOption = priceOption;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Unit getUnit() {
        return unit;
    }

    public void setUnit(Unit unit) {
        this.unit = unit;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public PriceOption getPriceOption() {
        return priceOption;
    }

    public void setPriceOption(PriceOption priceOption) {
        this.priceOption = priceOption;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Orderdetail{");
        sb.append("name='").append(name).append('\'');
        sb.append(", unit=").append(unit);
        sb.append(", price=").append(priceOption);
        sb.append(", user=").append(user);
        sb.append('}');
        return sb.toString();
    }
}

А вот код моей репозитории:

@RepositoryRestResource(path = "orderdetail")
public interface IOrderdetailRepository extends JpaRepository<Orderdetail, BigInteger>, CustomOrderdetailRepository {

    @Override
    @SuppressWarnings("unchecked")
    default Orderdetail save(Orderdetail entity)
    {
        return customSave(entity);
    }

}
public interface CustomOrderdetailRepository {

    <S extends Orderdetail> S customSave(S entity);

    Iterable<Orderdetail> findAll(Sort sort);

    Page<Orderdetail> findAll(Pageable pageable);

    Page<Orderdetail> findAll(Specification<Orderdetail> spec, Sort sort);
}
@RepositoryRestController
public class CustomOrderdetailRepositoryImpl implements CustomOrderdetailRepository {
    @Autowired
    private EntityManager entityManager;

    @Autowired
    private IUserRepository userRepository;

    @Override
    public <S extends Orderdetail> S customSave(S entity) {
        if (entity.getId() == null)
            this.entityManager.persist(entity);
        else
            this.entityManager.merge(entity);

        this.entityManager.flush();
        this.entityManager.clear();

        return (S) this.entityManager.find(Orderdetail.class, entity.getId());
    }
...
}

и моя JpaConfiguration:

@Configuration
@PropertySource({ "classpath:persistence.properties" })
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "de.orderbook.repository")
public class JpaConfiguration {

    @Autowired
    private Environment env;

    @Bean
    public Map<String, Object> jpaProperties() {
        Map<String, Object> props = new HashMap<String, Object>();
        props.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
        props.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
        props.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
        props.put("hibernate.format_sql", env.getProperty("hibernate.format_sql"));
//      props.put("hibernate.cache.provider_class", HashtableCacheProvider.class.getName());
        return props;
    }

    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
        hibernateJpaVendorAdapter.setShowSql(false);
        hibernateJpaVendorAdapter.setGenerateDdl(true);
        hibernateJpaVendorAdapter.setDatabase(Database.MYSQL);
        return hibernateJpaVendorAdapter;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new JpaTransactionManager( localContainerEntityManagerFactoryBean().getObject() );
    }

    @Bean(name = "entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean() {
        LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
        lef.setDataSource(dataSource());
        lef.setJpaPropertyMap(this.jpaProperties());
        lef.setJpaVendorAdapter(this.jpaVendorAdapter());
        lef.setPersistenceXmlLocation("classpath:META-INF/persistence2.xml");
        lef.setPackagesToScan("de.orderbook.model");
        return lef;
    }

    @Bean
    public DataSource dataSource() {
        final DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
        dataSource.setUrl(env.getProperty("jdbc.url"));
        dataSource.setUsername(env.getProperty("jdbc.user"));
        dataSource.setPassword(env.getProperty("jdbc.pass"));
        return dataSource;
    }

}

мой простой тест

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@AutoConfigureMockMvc
@ContextConfiguration(classes = {SecurityConfig.class, JpaConfiguration.class, RepositoryRestConfig.class, TestConfig.class})
@PropertySource(value = "classpath:application.yml")
public class TestInsertOrderdetail {
    @Autowired
    private IOrderdetailRepository orderDetailRepository;

    @Autowired
    private IUnitRepository unitRepository;

    @Autowired
    private IUserRepository userRepository;

    @Test
    public void insertOrderdetailTest() {
        Unit unit = this.unitRepository.save(new Unit("Stück"));
        User user = this.userRepository.save(new User("anni"));
        Orderdetail orderdetail = new Orderdetail("Heizung ausbauen", unit, user, new PriceOption(1, BigDecimal.valueOf(50)));
        this.orderDetailRepository.save(orderdetail);
    }
}

и Sql -выход:

2020-04-13 20:43:04.308 DEBUG 669728 --- [           main] org.hibernate.SQL                        : 
    insert 
    into
        "orderdetail"
        (changed_at, created_at, name, price, price_count, unit_id, user_id, id) 
    values
        (?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: 
    insert 
    into
        "orderdetail"
        (changed_at, created_at, name, price, price_count, unit_id, user_id, id) 
    values
        (?, ?, ?, ?, ?, ?, ?, ?)
2020-04-13 20:43:04.310 TRACE 669728 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [TIMESTAMP] - [2020-04-13 20:43:02.508]
2020-04-13 20:43:04.311 TRACE 669728 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [3] as [VARCHAR] - [Heizung ausbauen]
2020-04-13 20:43:04.312 TRACE 669728 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [4] as [NUMERIC] - [50]
2020-04-13 20:43:04.316 TRACE 669728 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [5] as [INTEGER] - [1]
2020-04-13 20:43:04.317 TRACE 669728 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [6] as [NUMERIC] - [1]
2020-04-13 20:43:04.318 TRACE 669728 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [7] as [NUMERIC] - [2]
2020-04-13 20:43:04.319 TRACE 669728 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [8] as [NUMERIC] - [3]
2020-04-13 20:43:04.322 DEBUG 669728 --- [           main] org.hibernate.SQL                        : 
    update
        "orderdetail" 
    set
        changed_at=?,
        created_at=?,
        name=?,
        price=?,
        price_count=?,
        unit_id=?,
        user_id=? 
    where
        id=? 
        and changed_at=?
Hibernate: 
    update
        "orderdetail" 
    set
        changed_at=?,
        created_at=?,
        name=?,
        price=?,
        price_count=?,
        unit_id=?,
        user_id=? 
    where
        id=? 
        and changed_at=?
2020-04-13 20:43:04.324 TRACE 669728 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [TIMESTAMP] - [2020-04-13 20:43:04.301]
2020-04-13 20:43:04.326 TRACE 669728 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [3] as [VARCHAR] - [Heizung ausbauen]
2020-04-13 20:43:04.326 TRACE 669728 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [4] as [NUMERIC] - [50]
2020-04-13 20:43:04.327 TRACE 669728 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [5] as [INTEGER] - [1]
2020-04-13 20:43:04.328 TRACE 669728 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [6] as [NUMERIC] - [1]
2020-04-13 20:43:04.330 TRACE 669728 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [7] as [NUMERIC] - [2]
2020-04-13 20:43:04.331 TRACE 669728 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [8] as [NUMERIC] - [3]
2020-04-13 20:43:04.332 TRACE 669728 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [9] as [TIMESTAMP] - [2020-04-13 20:43:02.508]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...