Hibernate 4:为什么我得到AnnotationException:Unknown mappedBy?

时间:2014-02-25 14:36:57

标签: java hibernate schema

我正在尝试从Hibernate Entities生成sql架构。这是我的实体:

学生实体

@Entity
@Table(name = "address") 
public class Address {

     @Id
     private long id;  

     @Column(name = "address")  
     private String address;  

     @Column(name = "city")  
     private String city;  

     @Column(name = "state")  
     private String state;  

     @Column(name = "country")  
     private String country;  

     @OneToOne (mappedBy="student")  
     private Student student;  

     public Address(){  

     }  

     public Address(String address, String city, String state,  
       String country) {  
      this.address = address;  
      this.city = city;  
      this.state = state;  
      this.country = country;  
     }  
  • getter and setters

    }

地址实体

@Entity  
@Table(name = "student") 
public class Student {

    @Id
    @GeneratedValue
    @Column(name = "student_id")  
    private long id;  

    @Column(name = "first_name")  
    private String firstName;  

    @Column(name = "last_name")  
    private String lastName;  

    @Column(name = "email")  
    private String email;  

    @Column(name = "phone")  
    private String phone;  

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="ADDRESS_ID")
    private Address address;  

    public Student(){  

    }  

    public Student(String firstName, String lastName, String email, String phone) {  
     this.firstName = firstName;  
     this.lastName = lastName;  
     this.phone = phone;  
     this.email = email;  
    }  

+ getters and setters   

}

生成架构类

    public class SchemaGenerator {


        private Configuration cfg;

        @SuppressWarnings("rawtypes")
        public SchemaGenerator(String packageName) throws Exception {
            cfg = new Configuration();
            cfg.setProperty("hibernate.hbm2ddl.auto", "create");

            for (Class clazz : getClasses(packageName)) {
                cfg.addAnnotatedClass(clazz);
            }
        }

        public static void main(String[] args) throws Exception {
            //final String packageName = args[0];
            final String packageName ="com.startup.app.models.entities";
            SchemaGenerator gen = new SchemaGenerator(packageName);
           // final String directory = args[1];
            final String directory = "E:\\Informatique\\workspace\\startup\\src\\main\\resources\\sql\\";
            gen.generate(Dialect.MYSQL, directory);
            gen.generate(Dialect.POSTGRESQL, directory);
        }



    private List<Class> getClasses(String packageName) throws Exception {
        File directory = null;
        try {
            ClassLoader cld = getClassLoader();
            URL resource = getResource(packageName, cld);
            directory = new File(resource.getFile());
        } catch (NullPointerException ex) {
            throw new ClassNotFoundException(packageName + " (" + directory
                    + ") does not appear to be a valid package");
        }
        return collectClasses(packageName, directory);
    }

    private ClassLoader getClassLoader() throws ClassNotFoundException {
        ClassLoader cld = Thread.currentThread().getContextClassLoader();
        if (cld == null) {
            throw new ClassNotFoundException("Can't get class loader.");
        }
        return cld;
    }

    private URL getResource(String packageName, ClassLoader cld) throws ClassNotFoundException {
        String path = packageName.replace('.', '/');
        URL resource = cld.getResource(path);
        if (resource == null) {
            throw new ClassNotFoundException("No resource for " + path);
        }
        return resource;
    }

    private List<Class> collectClasses(String packageName, File directory) throws ClassNotFoundException {
        List<Class> classes = new ArrayList<Class>();
        if (directory.exists()) {
            String[] files = directory.list();
            for (String file : files) {
                if (file.endsWith(".class")) {
                    // removes the .class extension
                    classes.add(Class.forName(packageName + '.'
                            + file.substring(0, file.length() - 6)));
                }
            }
        } else {
            throw new ClassNotFoundException(packageName
                    + " is not a valid package");
        }
        return classes;
    }

    private void generate(Dialect dialect, String directory) {
        cfg.setProperty("hibernate.dialect", dialect.getDialectClass());
        SchemaExport export = new SchemaExport(cfg);
        export.setDelimiter(";");
        export.setOutputFile(directory + "ddl_" + dialect.name().toLowerCase() + ".sql");
        export.setFormat(true);
        export.execute(true, false, false, false);
    }


    private static enum Dialect {
        MYSQL("org.hibernate.dialect.MySQLDialect"),
        POSTGRESQL("org.hibernate.dialect.PostgreSQLDialect");

        private String dialectClass;

        private Dialect(String dialectClass) {
            this.dialectClass = dialectClass;
        }

        public String getDialectClass() {
            return dialectClass;
        }
    }


 }

但我不明白为什么当我尝试生成架构时,我有以下错误:

INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
Exception in thread "main" org.hibernate.AnnotationException: Unknown mappedBy in: com.davy.app.domain.onetoone.one.entities.Address.student, referenced property unknown: com.davy.app.domain.onetoone.one.entities.Student.student
    at org.hibernate.cfg.OneToOneSecondPass.doSecondPass(OneToOneSecondPass.java:158)
    at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1586)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1359)
    at org.hibernate.cfg.Configuration.generateDropSchemaScript(Configuration.java:927)
    at org.hibernate.tool.hbm2ddl.SchemaExport.<init>(SchemaExport.java:189)
    at org.hibernate.tool.hbm2ddl.SchemaExport.<init>(SchemaExport.java:157)
    at com.davy.app.domain.utils.SchemaGenerator.generate(SchemaGenerator.java:103)
    at com.davy.app.domain.utils.SchemaGenerator.main(SchemaGenerator.java:36)

3 个答案:

答案 0 :(得分:1)

您正在尝试使用相同的表名“学生”更改

    @Table(name = "student") 

到另一个名字,比如

    @Table(name = "address") 

在班级地址。

答案 1 :(得分:0)

mappedBy定义在另一侧映射关联的属性的名称。在您的情况下,它不是student而是address,例如

public class Address {
  @OneToOne (mappedBy="address")  //<- not "student"
  private Student student; 
}  

public class Student {
  @OneToOne(cascade = CascadeType.ALL)
  @JoinColumn(name="ADDRESS_ID")
  private Address address; //<- this maps the association and thus is the value for the corresponding mappedBy
}  

除此之外,还存在其他映射错误,例如用作saran的相同表名指出。

答案 2 :(得分:0)

我找到了解决方案。问题是关于(类地址):

 @OneToOne (mappedBy="student")  
 private Student student;

Avec将其更改为

 @OneToOne 
private Student student;

实体学生,我添加了mappedBy:

 @OneToOne(cascade = CascadeType.ALL,mappedBy="student")
    @JoinColumn(name="ADDRESS_ID")
    private Address address;