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]