ошибка во время операции MassIndexer: отключенный объект передан для сохранения, HSEARCH000058: HSEARCH000116

У меня проблема во время работы massindexer.

Я использую JPA 2.0-cr-1, Hibernate search 4.2.0.Final с hibernate 4.1.9.Final и lucene версии 3.6.2. Я также использую пружинный каркас.

Похоже, у меня возникли проблемы, так как я использую поиск 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();
    }

Дальше массиндексер делает свою работу, но есть ошибки (не для всех данных пользователя):

[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)

Любая идея ?


person Nico    schedule 05.02.2013    source источник
comment
Я не думаю, что указанная выше ошибка исходит от индексатора массы. Прежде всего, MassIndexer только читает данные, а не сохраняет их. Во-вторых, код, который вы показываете, должен индексировать сущность User, но ошибка возникает из-за сохранения Контракта сущности. Думаю, там происходит больше, чем мы можем увидеть в вашем посте.   -  person Hardy    schedule 07.02.2013


Ответы (1)


Похоже, это происходит, когда вы пытаетесь сохранить сущность, идентификатор которой уже существует. Если вы предполагаете, что MassIndexer будет обновлять записи контракта в указанной ошибке, то я считаю, что вы захотите изменить аннотацию CascadeType на: CascadeType.ALL (или, возможно, CascadeType.SAVE_UPDATE).

Взгляните на этот вопрос, который обсуждает это исключение далее.

person femtoRgon    schedule 05.02.2013