【发布时间】:2019-11-15 18:57:54
【问题描述】:
Product product = new Product();
product.setName( "foo" );
product.setPrice(BigDecimal.valueOf( 4.5 ) );
pm.create( product ); // pm delegates calls to an entity manager object using persist method and tx is immediately commited after the call
List<Product> products = pm.findAllProducts();
products.stream().forEach( System.out::println ); // New product is listed too.
pm.create( product ); // Causes no exception! But, as per API, it should.
products = pm.findAllProducts(); // Fetch successful
products.stream().forEach( System.out::println ); // No difference from first print.
根据persistence API,如果实体已经存在,则坚持(从pm.create 调用)抛出EntityExistsException,但它不会按照代码发生。
- 持久性提供程序 (PP) - EclipseLink。
- 为什么 PP 忽略重复仍然存在?
- PP 在什么情况下选择抛出异常?
编辑:
Product.java
注意:
- 为简洁起见,排除了 getter 和 setter(适用于所有字段)和 toString()。
- 我已尽力按照指南格式化代码,但它没有发生,请多多包涵。
@Entity @Table(name = "PRODUCTS") @XmlRootElement @NamedQueries({ @NamedQuery(name = "Product.findAll", query = "SELECT p FROM Product p") , @NamedQuery(name = "Product.findById", query = "SELECT p FROM Product p WHERE p.id = :id") , @NamedQuery(name = "Product.findByName", query = "SELECT p FROM Product p WHERE p.name like :name") , @NamedQuery(name = "Product.findByPrice", query = "SELECT p FROM Product p WHERE p.price = :price") , @NamedQuery(name = "Product.findByBestBefore", query = "SELECT p FROM Product p WHERE p.bestBefore = :bestBefore") , @NamedQuery(name = "Product.findByVersion", query = "SELECT p FROM Product p WHERE p.version = :version") , @NamedQuery(name = "Product.findTotal", query = "SELECT count(p.id), sum(p.price) FROM Product p WHERE p.id in :ids" })
公共类产品实现可序列化{
private static final long serialVersionUID = 1L; @Id @Basic(optional = false) @NotNull @SequenceGenerator( name="pidGen", sequenceName="PID_SEQ", allocationSize=1 ) @GeneratedValue( strategy=SEQUENCE, generator="pidGen" ) private Integer id; @Basic(optional = false) @NotNull @Size(min = 3, max = 40, message="{prod.name}") private String name; // @Max(value=?) @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation @Basic(optional = false) @NotNull @Max( value=1000, message="{prod.price.max}") @Min( value=1, message="{prod.price.min}") private BigDecimal price; @Column(name = "BEST_BEFORE") @Temporal(TemporalType.DATE) //private Date bestBefore; private LocalDate bestBefore; @Version private Integer version; public Product() { } public Product(Integer id) { this.id = id; } public Product(Integer id, String name, BigDecimal price) { this.id = id; this.name = name; this.price = price; } @Override public int hashCode() { int hash = 0; hash += (id != null ? id.hashCode() : 0); return hash; } @Override public boolean equals(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof Product)) { return false; } Product other = (Product) object; if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { return false; } return true; } }
【问题讨论】:
-
pm是什么的一个实例? -
显示产品实体
-
@AlanHay
pm是 POJO - 助手/实用程序/代表。create方法:public void create( @Valid Product product ) { em.getTransaction().begin(); em.persist( product ); em.getTransaction().commit(); } -
@MaciejKowalski 更新了 OP。
标签: jpa exception eclipselink persist