2014-02-25 59 views
0

我想從休眠實體生成sql模式。這裏是我的實體:Hibernate 4:爲什麼我得到AnnotationException:未知mappedBy?

學生實體

@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和setter

    }

地址實體

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

回答

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指出使用同一個表名。

1

您與同桌嘗試名稱「學生」變更

@Table(name = "student") 

以另一個名字類似

@Table(name = "address") 

at Class Address。

+0

是的,這是一個複製錯誤。粘貼代碼時我沒有注意。謝謝 – Pracede

0

我找到了解決方案。問題是關於(類ADRESS):

@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; 
+0

這會將學生映射到地址表中的某個student-id列,而不是學生表中列ADDRESS_ID的地址。 – Thomas

+0

你是對的,但在我的情況下,我認爲@JoinColumn沒有用 – Pracede

相關問題