2012-11-15 19 views
5

Ich verwende Hibernate 4.1.0.Final, JPA 2.0 und MySQL 5.5. Ich habe die folgende Einheit:Wie erstelle ich automatisch eine GUID für eine Join-Tabelle?

@GenericGenerator(name = "uuid-strategy", strategy = "uuid.hex") 
@Entity 
@Table(name = "cb_organization", uniqueConstraints = {@UniqueConstraint(columnNames={"organization_id"})}) 
public class Organization implements Serializable 
{ 

    … 

    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE}) 
    @JoinTable(name = "cb_organization_address", 
       joinColumns = @JoinColumn(name = "organization_id"), 
       inverseJoinColumns = @JoinColumn(name = "address_id")) 
    /* List of addresses associated with this organization */ 
    private List<Address> addresses; 

Beachten Sie die Join-Tabelle "cb_organization_address". Der Primärschlüssel ist ein varchar (32) not null Feld, das ich gerne eine GUID wäre, ähnlich der ID der Organisationseinheit. Wie erstelle ich automatisch eine ID für diese Tabelle? Wenn ich versuche, und eine Organisation mit Adressen speichern, erhalte ich die Ausnahme ...

javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Field 'ID' doesn't have a default value 
    org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1361) 
    org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1289) 
    org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1295) 
    org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:976) 
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    java.lang.reflect.Method.invoke(Method.java:597) 
    org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240) 
    $Proxy47.flush(Unknown Source) 
    org.mainco.subco.organization.repo.OrganizationDaoImpl.save(OrganizationDaoImpl.java:63) 
    org.mainco.subco.organization.service.OrganizationServiceImpl.save(OrganizationServiceImpl.java:64) 
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    java.lang.reflect.Method.invoke(Method.java:597) 
    org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318) 
    org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) 
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) 
    org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110) 
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) 
    $Proxy62.save(Unknown Source) 
    org.mainco.subco.sbadmin.controllers.OrganizationController.save(OrganizationController.java:204) 
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    java.lang.reflect.Method.invoke(Method.java:597) 
    org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213) 
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126) 
     org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96) 
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617) 
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578) 
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) 
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923) 
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852) 
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882) 
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:754) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:847) 
+0

Stellen Sie sicher, dass Sie kein Problem durch ein anderes ersetzen: http://www.codinghorror.com/blog/2007/03/primary-keys-ids-versus-guids.html – n8wrl

Antwort

1

sollten Sie keine ID für eine Join-Tabelle automatisch generieren. Stattdessen sollten Sie die ID-Spalte aus cb_organization_address entfernen.

Join-Tabellen haben in der Regel keine eigenen IDs, sie repräsentieren lediglich Assoziationen zwischen zwei Dingen. Daher ist die "Identität" der Beziehung selbst oft der zusammengesetzte Schlüssel der beiden Dinge, die miteinander in Beziehung stehen. Für Ihren Anwendungsfall würde ich sagen, dass dies das richtige Datenmodell ist: Jede Organisation kann eine beliebige Adresse null oder ein Mal haben, jede Adresse kann sich in einer beliebigen Anzahl von Organisationen befinden.