Grails 3.x: Re-using JPA/Hibernate Domain classes:

2019-02-23 15:07发布

问题:

I have a Spring 4.1.0 back-end application with domain classes annotated in JPA (w/Hibernate 4.3.5 as the persistence provider) using Maven as the build tool. I now want to add a web front-end component to this app and have decided to use Grails 3.x as my web framework. I want to re-use my existing JPA annotated domain classes with Grails and then use generate-all to create controllers and views for each domain model. My first milestone goal is to get basic CRUD functionality on the old domain models from this web app.

Following the information I found in the Grails documentation and in some older blog posts as well as some slightly related SO posts, I created a new Grails project and packaged up my existing project as a jar and installed it (I ran mvn install -DskipTests to be exact) and then added it to build.gradle (actually I just want to have one project in the end, but I thought I'd try it this way first because I don't want to wrestle with having Maven and Gradle in the same project yet):

 repositories {
 ...
 mavenLocal()
 ...
}
 dependencies {
 ...

 compile "com.my-company:my-spring-app:1.0.0.CI-SNAPSHOT"
 ...
}

No warnings or errors from IntelliJ IDEA 14 so far. Then I created the grails-app/conf/hibernate/hibernate.cfg.xml file and tried putting just one of my old JPA annotated entities in it for now:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration SYSTEM
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <mapping package="com.my-company.my-spring-app.domain" />
        <mapping class="com.my-company.my-spring-app.domain.City" />
    </session-factory>
</hibernate-configuration>

No complaints from the IDE here either. The City.java entity class looks something like:

package com.my-company.my-spring-app.domain;

import javax.persistence.*;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

/**
 * City generated by hbm2java
 */
@Entity
@Table(name = "city",
     schema = "public",
     uniqueConstraints = @UniqueConstraint(columnNames = "name"))
public class City implements java.io.Serializable {

private static final long serialVersionUID = 4674557242772722625L;

@Id
@SequenceGenerator(name = "city_gen",
                   schema = "public",
                   sequenceName = "city_id_seq")
@GeneratedValue(strategy = GenerationType.SEQUENCE,
                generator = "city_gen")
@Column(name = "id",
        unique = true,
        nullable = false)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "countryid",
            nullable = false)
// @JoinColumn(name = "country_id", nullable = false)
private Country country;

@Column(name = "name",
        unique = true,
        length = 200)
private String name;
...
}

Then I jumped into the Grails console and tried to generate the controller and views for the City domain class:

grails generate-all com.my-company.my-spring-app.domain.City

But I just get a Domain class not found error:

| Error domain class not found for name com.my-company.my-spring-app.domain.City

I quickly created a Grails 2.5.0 app, put the my-spring-app.jar in lib/ and tried this again to see if it was an issue with the 'bleeding edge' Grails 3.0.1 but got the same result.

Does anyone know what's going on here? How can I re-use my old JPA domain classes with Grails 3.x so that I can stay DRY with only one set of domain entities?

回答1:

I resolved a similar issue by putting hibernate.cfg.xml in grails-app/conf (not inside a hibernate subdirectory) as described in mapping-with-hibernate-annotations-in-grails-3-0-1.