2

guys. I wanted to create Fulltext search in my Spring Boot application with the help of Hibernate Search. And I faced with such an exception: java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead. It ocuurs on line

entityManager.getTransaction().begin();

Here is my code

@Repository
public class HibernateSearch {
  @PersistenceContext
  private EntityManager entityManager;

  @Transactional
  public List<Manual> fulltextSearching(String keyword){

    FullTextEntityManager fullTextEntityManager =
            org.hibernate.search.jpa.Search.getFullTextEntityManager(entityManager);
    entityManager.getTransaction().begin();

    QueryBuilder qb = fullTextEntityManager.getSearchFactory()
            .buildQueryBuilder().forEntity(Manual.class).get();
    org.apache.lucene.search.Query luceneQuery = qb
            .keyword()
            .onFields("name")
            .matching(keyword)
            .createQuery();

    javax.persistence.Query jpaQuery =
            fullTextEntityManager.createFullTextQuery(luceneQuery, Manual.class);

    @SuppressWarnings("unchecked")
    List<Manual> result =  jpaQuery.getResultList();

    entityManager.getTransaction().commit();
    entityManager.close();
    return result;
}

}

My entity:

@Entity
@Table(name = "manual")
@Getter
@Setter
@NoArgsConstructor
@Indexed
public class Manual {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = "manual_id")
  private Long id;

  @NotNull
  @Column(name = "manual_name")
  @Field
  private String name;
}

My properties:

spring.jpa.properties.hibernate.search.default.directory_provider = filesystem
spring.jpa.properties.hibernate.search.default.indexBase = D:\\Java

spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

My Maven dependencies:

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-search-orm</artifactId>
        <version>5.7.1.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
    </dependency>

If you need additional information to answer my question, say and I will add it. I searched for the net but still can't find the answer. I'll be very glad if you resolve my problem.

Andrey-2310
  • 531
  • 1
  • 6
  • 13
  • Remove the transaction code. Spring already managed your transaction and entity manager... – M. Deinum Jul 26 '17 at 11:34
  • @M.Deinum I tried it but when I remove transaction code the creation of luceneQuery throws NPE. org.apache.lucene.search.Query luceneQuery = qb .keyword() .onFields("name") .matching(keyword) .createQuery();That's why I'm a bit confused – Andrey-2310 Jul 26 '17 at 11:47
  • Then you have a different issue but you are now competing with Spring on transactions. The solution isn't to start a transaction the solution lies elsewhere. Remove the transaction code and rewrite your question so we can help to fix the `NullPointerException`. – M. Deinum Jul 26 '17 at 11:51
  • Possible duplicate of [NPE while creating org.apache.lucene.search.Query](https://stackoverflow.com/questions/45328071/npe-while-creating-org-apache-lucene-search-query) – yrodiere Jul 26 '17 at 16:01
  • I have the same problem and I have tried to use transaction from Spring and javax, neither helps. @yrodiere - This is not about lucene, but about Spring+hibernate. Absolutely different problem. – Gangnus Dec 06 '20 at 12:59
  • Both questions are about Hibernate Search, but you're right, they're not the same. The two questions were created a few hours apart and from a cursory glance they looked identical, but they were not. My bad. – yrodiere Dec 07 '20 at 07:53

2 Answers2

5

Maybe you should get entityManager from EntityManagerFactory:

@Autowired
private EntityManagerFactory emf;
...
EntityManager entityManager = emf.createEntityManager();
Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
0

Maybe you should use @Transactional annotation from javax.transaction package.
Works for me.

NickCoder
  • 1,504
  • 2
  • 23
  • 35
Parth Savaliya
  • 353
  • 6
  • 13