通过SO搜索,但我无法找到我的案例。
有一个实体卡,像这样:
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.NotEmpty;
@Entity
@ToString(exclude={"playRequirements"})
@Table(name = "CARD",
indexes = {@Index(name = "CARD_IDX_1", columnList="ID", unique = true)})
public class Card implements Serializable {
@Getter
@Setter
@NotEmpty
@NotBlank
@Id
@Column(name = "ID", unique = true, nullable = false)
private String id;
@Getter
@Setter
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="card")
private List<CardPlayRequirementsRel> playRequirements;
}
与实体CardPlayRequirementsRel的反向关系:
import java.io.Serializable;
import hscli.entities.domain.PlayRequirement;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.validator.constraints.NotEmpty;
@Entity
@ToString
@EqualsAndHashCode(of={"card", "playRequirement"})
@Table(name = "CARD_PLAY_REQUIREMENT_REL",
indexes=@Index(name="CARD_PLAY_REQ_REL_IDX_1", unique=true, columnList="CARD,PLAY_REQUIREMENT"))
public class CardPlayRequirementsRel implements Serializable {
@Id
@Getter
@Setter
@NotEmpty
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "CARD", nullable = false, foreignKey = @ForeignKey(name = "FK_CARD_PLAY_REQ_REL_CARD"))
private Card card;
@Id
@Getter
@Setter
@NotEmpty
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "PLAY_REQUIREMENT", nullable = false, foreignKey = @ForeignKey(name = "FK_CARD_PLAY_REQ_REL_PLAY_REQ"))
private PlayRequirement playRequirement;
@Getter
@Setter
@NotEmpty
@Column(name = "VALUE", nullable = false)
private Long value;
}
我想坚持一份名单:
[...]
List<CardDTO> dtoList = connectionService.getCardDTO();
List<Card> toSave = new ArrayList<Card>();
for(CardDTO dto : dtoList) {
log.debug("----------------> id: [" + dto.getId() + "]");
Card entity = new Card();
dtoToCardEntity(dto, entity);
toSave.add(entity);
}
cardRepository.save(toSave);
[...]
private void dtoToCardEntity(CardDTO dto, Card entity) {
entity.setId(dto.getId());
if(dto.getPlayRequirements() != null && CollectionUtils.isNotEmpty(dto.getPlayRequirements().keySet())) {
entity.setPlayRequirements(new ArrayList<CardPlayRequirementsRel>());
for(String playReq : dto.getPlayRequirements().keySet()) {
CardPlayRequirementsRel rel = new CardPlayRequirementsRel();
rel.setCard(entity);
rel.setPlayRequirement(domainBaseService.findOneByCodice(playReq, PlayRequirement.class));
rel.setValue(dto.getPlayRequirements().get(playReq));
entity.getPlayRequirements().add(rel);
}
}
}
但是在保存时我得到了这个例外:
13398 02:04:41,679 [main] DEBUG [org.hibernate.SQL:92] -
select
cardplayre0_.PLAY_REQUIREMENT as PLAY_REQUIREMENT2_7_0_,
cardplayre0_.CARD as CARD3_7_0_,
cardplayre0_.VALUE as VALUE1_7_0_
from
CARD_PLAY_REQUIREMENT_REL cardplayre0_
where
cardplayre0_.PLAY_REQUIREMENT=?
and cardplayre0_.CARD=?
13398 02:04:41,679 [main] TRACE [org.hibernate.type.descriptor.sql.BasicBinder:65] - binding parameter [1] as [VARCHAR] - [REQ_MINION_TARGET]
13399 02:04:41,680 [main] TRACE [org.hibernate.type.descriptor.sql.BasicBinder:65] - binding parameter [2] as [VARCHAR] - [AT_024]
13404 02:04:41,685 [main] ERROR [hscli.HearthStoneCardListImporter:56] - A different object with the same identifier value was already associated with the session : [hscli.entities.cards.CardPlayRequirementsRel#CardPlayRequirementsRel(card=null, playRequirement=null, value=0)]; nested exception is javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [hscli.entities.cards.CardPlayRequirementsRel#CardPlayRequirementsRel(card=null, playRequirement=null, value=0)]
org.springframework.dao.DataIntegrityViolationException: A different object with the same identifier value was already associated with the session : [hscli.entities.cards.CardPlayRequirementsRel#CardPlayRequirementsRel(card=null, playRequirement=null, value=0)]; nested exception is javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [hscli.entities.cards.CardPlayRequirementsRel#CardPlayRequirementsRel(card=null, playRequirement=null, value=0)]
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:410)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:246)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:491)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy41.save(Unknown Source)
at hscli.services.impl.CardServiceImpl.updateCards(CardServiceImpl.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy44.updateCards(Unknown Source)
at hscli.HearthStoneCardListImporter.updateCards(HearthStoneCardListImporter.java:54)
at hscli.HearthStoneCardListImporter.main(HearthStoneCardListImporter.java:29)
Caused by: javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [hscli.entities.cards.CardPlayRequirementsRel#CardPlayRequirementsRel(card=null, playRequirement=null, value=0)]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1664)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1171)
at sun.reflect.GeneratedMethodAccessor36.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298)
at com.sun.proxy.$Proxy39.merge(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:509)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:540)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:72)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:503)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:488)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:460)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
... 23 more
答案 0 :(得分:0)
如果您的实体中有多个使用@Id
注释的列,则必须使用@IdClass
注释或将其替换为嵌入式@EmbeddedId
。请参阅How to map a composite key with Hibernate?以获得一个很好的解释,它似乎与hibernate无关。
我不完全确定这实际上是你现在看到的问题,因为Exception似乎抱怨id字段为null
的多个实例,所以既然你没有指定任何生成器,您应确保将id列设置为实际值且不为null。