我在massindexer操作期间遇到了一个问题。
我使用JPA 2.0-cr-1,Hibernate搜索4.2.0.Final和hibernate 4.1.9.Final,以及lucene版本3.6.2。 我也使用spring框架。
我使用Hibernate搜索4.2.0.Final代替Hibernate搜索3.3.0.Final似乎有问题。
我将实体User.java编入索引:
@Entity
@Table(name = "user", uniqueConstraints = {
@UniqueConstraint(columnNames = "email"),
@UniqueConstraint(columnNames = "login") })
@Indexed
@FullTextFilterDefs({
@FullTextFilterDef(name = "userFilterGroup", impl = UserFilterGroupFactory.class ,cache=FilterCacheModeType.NONE),
@FullTextFilterDef(name = "userFilterAccountType", impl = LuceneStrFilterFactory.class ,cache=FilterCacheModeType.NONE)})
public class User extends TemporalBehavior implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = -626437341655804022L;
public static final String[] SEARCH_FIELDS = new String[]{"id","login","email","profile.lastname","profile.firstname"};
private Integer id;
@Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
@NotNull
@Size(min=1, max=255)
//@Size(min=6, max=255) //L'ancienne plateforme permet des login min=1
private String login;
@NotNull
@Size(min=1, max=255)
//@Size(min=6, max=255) //L'ancienne plateforme permet des pass min=1
private String password;
@Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
@Email
private String email;
@Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
private String partnerRef;
private Set<Contract> contracts = new HashSet<Contract>(0);
private Set<Contract> ownedContracts = new HashSet<Contract>();
....
@ManyToMany(fetch = FetchType.LAZY, cascade=CascadeType.PERSIST)
@JoinTable(name = "user_contract", joinColumns = { @JoinColumn(name = "user_id", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "contract_id", nullable = false, updatable = false) })
public Set<Contract> getContracts() {
return this.contracts;
}
@OneToMany(mappedBy="owner")
public Set<Contract> getOwnedContracts() {
return this.ownedContracts;
}
...
}
我称之为Massindexer操作:
FullTextEntityManager fem = Search.getFullTextEntityManager(em);
try {
fem.createIndexer(User.class)
.purgeAllOnStart(true)
.optimizeAfterPurge( true )
.optimizeOnFinish( true )
.batchSizeToLoadObjects(100)
.threadsForSubsequentFetching(8)
.threadsToLoadObjects(4)
.cacheMode(CacheMode.NORMAL) // todo : It is recommended to leave cacheMode to CacheMode.IGNORE (the default), as in most reindexing situations the cache will be a useless additional overhead;
.startAndWait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
然后massindexer完成它的工作但是有一些错误(不适用于所有用户数据):
[05-02-2013 13:06:11:086] ERROR org.hibernate.search.exception.impl.LogErrorHandler - HSEARCH000058: HSEARCH000116: Unexpected error during MassIndexer operation
org.hibernate.PersistentObjectException: detached entity passed to persist: com.mycompany.prj.model.commercial.Contract
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:141)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:78)
at org.hibernate.tuple.entity.AbstractEntityTuplizer$IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller.getIdentifier(AbstractEntityTuplizer.java:491)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:337)
at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:4491)
at org.hibernate.event.internal.DefaultLockEventListener.onLock(DefaultLockEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireLock(SessionImpl.java:810)
at org.hibernate.internal.SessionImpl.fireLock(SessionImpl.java:799)
at org.hibernate.internal.SessionImpl.access$1700(SessionImpl.java:175)
at org.hibernate.internal.SessionImpl$LockRequestImpl.lock(SessionImpl.java:2361)
at org.hibernate.engine.spi.CascadingAction$2.cascade(CascadingAction.java:178)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:383)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:326)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:412)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:353)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:329)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
at org.hibernate.event.internal.DefaultLockEventListener.cascadeOnLock(DefaultLockEventListener.java:92)
at org.hibernate.event.internal.DefaultLockEventListener.onLock(DefaultLockEventListener.java:82)
at org.hibernate.internal.SessionImpl.fireLock(SessionImpl.java:810)
at org.hibernate.internal.SessionImpl.fireLock(SessionImpl.java:799)
at org.hibernate.internal.SessionImpl.access$1700(SessionImpl.java:175)
at org.hibernate.internal.SessionImpl$LockRequestImpl.lock(SessionImpl.java:2361)
at org.hibernate.engine.spi.CascadingAction$2.cascade(CascadingAction.java:178)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:383)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:326)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
at org.hibernate.event.internal.DefaultLockEventListener.cascadeOnLock(DefaultLockEventListener.java:92)
at org.hibernate.event.internal.DefaultLockEventListener.onLock(DefaultLockEventListener.java:82)
at org.hibernate.internal.SessionImpl.fireLock(SessionImpl.java:810)
at org.hibernate.internal.SessionImpl.fireLock(SessionImpl.java:803)
at org.hibernate.internal.SessionImpl.access$1800(SessionImpl.java:175)
at org.hibernate.internal.SessionImpl$LockRequestImpl.lock(SessionImpl.java:2364)
at org.hibernate.search.batchindexing.impl.EntityConsumerLuceneWorkProducer.indexAllQueue(EntityConsumerLuceneWorkProducer.java:133)
at org.hibernate.search.batchindexing.impl.EntityConsumerLuceneWorkProducer.run(EntityConsumerLuceneWorkProducer.java:104)
at org.hibernate.search.batchindexing.impl.OptionallyWrapInJTATransaction.run(OptionallyWrapInJTATransaction.java:132)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:680)
有什么想法吗?
答案 0 :(得分:1)
当您尝试持久存在其ID已存在的实体时,似乎会发生这种情况。如果你打算MassIndexer更新Contract记录,在给出的错误中,我相信你会想要将CascadeType注释更改为:CascadeType.ALL
(或者CascadeType.SAVE_UPDATE
)。
查看this question,进一步讨论此异常。