I have a problem with using JPA annotated class in Grails (tried on grails-3.1.11 and grails-3.2.0) in my test application.
I followed description in Grails documentation mappingWithHibernateAnnotation and multiple answers on Stackoverflow for similar problems (question 1, question 2 and question 3), but no luck. Here is a description what I do (same on both versions of Grails):1. Create a new Grails project (I'm using IntelliJ Idea 2016.2.4).
2. Set up a datasource in application.yml:
dataSource:
configClass: org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration.class
pooled: true
jmxExport: true
dialect: org.hibernate.dialect.PostgreSQLDialect
driverClassName: org.postgresql.Driver
username: postgres
password: masterkey
3. Add PostgreSQL JDBC dependency to build.grandle:
compile group: 'org.postgresql', name: 'postgresql', version: '9.4-1200-jdbc41'
4. Create a new class DictionaryEntity.groovy in src/main/groovy:
package persistence.postgresql.mapping
import javax.persistence.*;
@Entity(name = "persistence.postgresql.mapping.DictionaryEntity")
@Table(name = "dictionary")
public class DictionaryEntity implements Serializable {
private int id;
private int word;
private int language;
private String txt;
@SequenceGenerator(name = "dictionary_id_seq_gen", sequenceName = "dictionary_id_seq", allocationSize = 1)
@Id
@GeneratedValue(generator = "dictionary_id_seq_gen", strategy = GenerationType.SEQUENCE)
@Column(name = "id", nullable = false)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name = "word", nullable = false)
public int getWord() {
return word;
}
public void setWord(int word) {
this.word = word;
}
@Column(name = "language", nullable = false)
public int getLanguage() {
return language;
}
public void setLanguage(int language) {
this.language = language;
}
@Column(name = "txt", length = 128)
public String getTxt() {
return txt;
}
public void setTxt(String txt) {
this.txt = txt;
}
public DictionaryEntity() {
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DictionaryEntity that = (DictionaryEntity) o;
if (id != that.id) return false;
if (word != that.word) return false;
if (language != that.language) return false;
if (txt != null ? !txt.equals(that.txt) : that.txt != null) return false;
return true;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + word;
result = 31 * result + language;
result = 31 * result + (txt != null ? txt.hashCode() : 0);
return result;
}
}
5. Create hibernate.cfg.xml in grails-app/conf directory (tried grails-app/conf/hibernate as well):
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="persistence.postgresql.mapping.DictionaryEntity"/>
</session-factory>
</hibernate-configuration>
6. Created a new DictionaryEntityController in grails-app/controllers/grailsproj directory (scaffolding plugin has included to dependencies):
package grailsproj
import persistence.postgresql.mapping.DictionaryEntity
class DictionaryEntityController {
static scaffold = DictionaryEntity
}
When I'm running the application there is no domain classes ("Domains: 0" in Artefacts). If I go to my controller ("/dictionaryEntity/index") I'm getting the following error:
ERROR org.grails.web.errors.GrailsExceptionResolver - MissingMethodException occurred when processing request: [GET] /dictionaryEntity/index
No signature of method: static persistence.postgresql.mapping.DictionaryEntity.count() is applicable for argument types: () values: []
Possible solutions: print(java.lang.Object), print(java.io.PrintWriter), wait(), find(), collect(), any(). Stacktrace follows:
java.lang.reflect.InvocationTargetException: null
at org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControllerClass.java:210)
at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:187)
at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: groovy.lang.MissingMethodException: No signature of method: static persistence.postgresql.mapping.DictionaryEntity.count() is applicable for argument types: () values: []
Possible solutions: print(java.lang.Object), print(java.io.PrintWriter), wait(), find(), collect(), any()
at grails.rest.RestfulController.countResources(RestfulController.groovy:277)
at grails.rest.RestfulController.index(RestfulController.groovy:64)
at grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:96)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93)
... 14 common frames omitted
Looks like DictionaryEntity hasn't recognized as domain class. My pure Java+Hibernate application works fine with the same mapping class so I need your advice how to resolve this issue.
Update
Added annotation @grails.gorm.Entity regarding to Joshua's answer, the error has changed to:
Either class [persistence.postgresql.mapping.DictionaryEntity] is not a domain class or GORM has not been initialized correctly or has already been shutdown. Ensure GORM is loaded and configured correctly before calling any methods on a GORM entity.