【发布时间】:2017-11-07 09:36:07
【问题描述】:
我正在尝试使用 Spring Data/Crud Repository(.save) 在 DB 中保存一个实体,其中包含另一个通过 @Cache 方法加载的实体。换句话说,我正在尝试保存一个包含属性实体的广告实体,并且这些属性是使用 Spring @Cache 加载的。
正因为如此,我将一个分离的实体传递给了 Persist 异常。
我的问题是,有没有办法保存仍然使用@Cache 作为属性的实体?
我查了一下,但找不到任何人在做同样的事情,特别是知道我正在使用只有方法 .save() 的 CrudRepository,据我所知,它管理 Persist、Update、Merge 等。
非常感谢任何帮助。
提前致谢。
Ad.java
@Entity
@DynamicInsert
@DynamicUpdate
@Table(name = "ad")
public class Ad implements SearchableAdDefinition {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private User user;
@OneToMany(mappedBy = "ad", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Set<AdAttribute> adAttributes;
(.....) }
AdAttribute.java
@Entity
@Table(name = "attrib_ad")
@IdClass(CompositeAdAttributePk.class)
public class AdAttribute {
@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ad_id")
private Ad ad;
@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "attrib_id")
private Attribute attribute;
@Column(name = "value", length = 75)
private String value;
public Ad getAd() {
return ad;
}
public void setAd(Ad ad) {
this.ad = ad;
}
public Attribute getAttribute() {
return attribute;
}
public void setAttribute(Attribute attribute) {
this.attribute = attribute;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
@Embeddable
class CompositeAdAttributePk implements Serializable {
private Ad ad;
private Attribute attribute;
public CompositeAdAttributePk() {
}
public CompositeAdAttributePk(Ad ad, Attribute attribute) {
this.ad = ad;
this.attribute = attribute;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CompositeAdAttributePk compositeAdAttributePk = (CompositeAdAttributePk) o;
return ad.getId().equals(compositeAdAttributePk.ad.getId()) && attribute.getId().equals(compositeAdAttributePk.attribute.getId());
}
@Override
public int hashCode() {
return Objects.hash(ad.getId(), attribute.getId());
}
}
加载属性的方法:
@Cacheable(value = "requiredAttributePerCategory", key = "#category.id")
public List<CategoryAttribute> findRequiredCategoryAttributesByCategory(Category category) {
return categoryAttributeRepository.findCategoryAttributesByCategoryAndAttribute_Required(category, 1);
}
用于创建/保留广告的方法:
@Transactional
public Ad create(String title, User user, Category category, AdStatus status, String description, String url, Double price, AdPriceType priceType, Integer photoCount, Double minimumBid, Integer options, Importer importer, Set<AdAttribute> adAtributes) {
//Assert.notNull(title, "Ad title must not be null");
Ad ad = adCreationService.createAd(title, user, category, status, description, url, price, priceType, photoCount, minimumBid, options, importer, adAtributes);
for (AdAttribute adAttribute : ad.getAdAttributes()) {
adAttribute.setAd(ad);
/* If I add this here, I don't face any exception, but then I don't take benefit from using cache:
Attribute attribute = attributeRepository.findById(adAttribute.getAttribute().getId()).get();
adAttribute.setAttribute(attribute);
*/
}
ad = adRepository.save(ad);
solrAdDocumentRepository.save(AdDocument.adDocumentBuilder(ad));
return ad;
}
【问题讨论】:
-
请发布您的代码
-
也许这可以提供一些关于分离实体的见解? stackoverflow.com/questions/8441450/…
-
刚刚发布了代码,@BikramjitRajbongshi。
-
会看看,@ValentinGrégoire,谢谢你的建议。我用代码更新了帖子,以防你也想看。谢谢!
标签: spring hibernate jpa spring-data spring-data-jpa