postgresql 休眠 UUID 作为 UUID 类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25611285/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate UUID as UUID type
提问by xenoterracide
Trying to use a UUID
as my id for PostgreSQL and H2, the current exceptions are for H2
尝试使用 aUUID
作为我的 PostgreSQL 和 H2 id,当前的例外情况是 H2
java.lang.IllegalArgumentException: Can not set java.util.UUID field com.lm.model.Task.id to java.lang.String
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
at java.lang.reflect.Field.set(Field.java:758)
at org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:122)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.setIdentifier(AbstractEntityTuplizer.java:381)
at org.hibernate.persister.entity.AbstractEntityPersister.setIdentifier(AbstractEntityPersister.java:4751)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:184)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:137)
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:84)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:342)
at com.sun.proxy.$Proxy68.persist(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:289)
at com.sun.proxy.$Proxy68.persist(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:389)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:405)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:390)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:344)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor.proceedWithInvocation(TransactionInterceptor.java:98)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:111)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy70.save(Unknown Source)
at org.springframework.data.rest.core.invoke.CrudRepositoryInvoker.invokeSave(CrudRepositoryInvoker.java:106)
at org.springframework.data.rest.webmvc.RepositoryEntityController.createAndReturn(RepositoryEntityController.java:383)
at org.springframework.data.rest.webmvc.RepositoryEntityController.postCollectionResource(RepositoryEntityController.java:211)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:683)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1720)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1679)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Here's my entity
这是我的实体
@Entity
@Table(name = "tasks")
public class Task {
private static final Logger log = LoggerFactory.getLogger(Task.class);
@Id
@NotNull
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
@Column(name = "task_id", columnDefinition = "uuid")
private UUID id;
@NotNull
@NotEmpty
@Size(min = 1, max = 120)
private String description;
public String getDescription () {
return description;
}
public void setDescription (final String description) {
this.description = description;
}
public UUID getId () {
return id;
}
public void setId ( final UUID uuid ) {
id = uuid;
}
}
I'm not sure if it's relevant, but I'm using a Spring Data Rest Repository to persist this.
我不确定它是否相关,但我正在使用 Spring Data Rest Repository 来保留它。
I would like to be able to persist, ultimately, as the native type in PostgreSQL, and whatever it is H2 needs the UUID to be (I'm fairly new to H2).
我希望最终能够作为 PostgreSQL 中的本机类型坚持下去,无论 H2 是什么,都需要 UUID(我对 H2 还很陌生)。
回答by xenoterracide
Update:with Hibernate 5 I was able to get more cross database compatible UUID's included(note: I am not the implementor, though I did give it a stab).
更新:使用 Hibernate 5,我能够获得更多跨数据库兼容的 UUID(注意:我不是实现者,但我确实尝试了它)。
@Entity
public class MyEntity {
@Id
@GeneratedValue
@Column( columnDefinition = "uuid", updatable = false )
public UUID getId() {
return id;
}
}
Original
原来的
Dzone posted an article about a second version of the UUID generator last year
Dzone 去年发表了一篇关于 UUID 生成器第二个版本的文章
first create your own usertype (at least until hibernate implements similar)
首先创建自己的用户类型(至少在 hibernate 实现类似之前)
public class UUIDType extends AbstractSingleColumnStandardBasicType<UUID> {
public static final String NAME = "uuid-name";
public static final UUIDType INSTANCE = new UUIDType();
public UUIDType() {
super( UUIDSqlTypeDescriptor.INSTANCE, UUIDTypeDescriptor.INSTANCE );
}
public String getName() {
return NAME;
}
public static class UUIDSqlTypeDescriptor implements SqlTypeDescriptor {
public static final UUIDSqlTypeDescriptor INSTANCE = new UUIDSqlTypeDescriptor();
public int getSqlType() {
// ugh
return Types.VARCHAR;
}
@Override
public boolean canBeRemapped() {
return true;
}
public <X> ValueBinder<X> getBinder( final JavaTypeDescriptor<X> javaTypeDescriptor ) {
return new BasicBinder<X>( javaTypeDescriptor, this ) {
@Override
protected void doBind( PreparedStatement st, X value, int index, WrapperOptions options )
throws SQLException {
st.setObject( index, javaTypeDescriptor.unwrap( value, UUID.class, options ) );
}
};
}
public <X> ValueExtractor<X> getExtractor( final JavaTypeDescriptor<X> javaTypeDescriptor ) {
return new BasicExtractor<X>( javaTypeDescriptor, this ) {
@Override
protected X doExtract( ResultSet rs, String name, WrapperOptions options ) throws SQLException {
return javaTypeDescriptor.wrap( rs.getObject( name ), options );
}
@Override
protected X doExtract( CallableStatement statement, int index, WrapperOptions options )
throws SQLException {
return javaTypeDescriptor.wrap( statement.getObject( index ), options );
}
@Override
protected X doExtract( CallableStatement statement, String name, WrapperOptions options )
throws SQLException {
return javaTypeDescriptor.wrap( statement.getObject( name ), options );
}
};
}
}
}
Then annotate your models package-info.java
然后注释你的模型 package-info.java
@TypeDef(
name = UUIDType.NAME,
defaultForType = UUID.class,
typeClass = UUIDType.class
)
package com.xenoterracide.rpf.model;
import org.hibernate.annotations.TypeDef;
import org.hibernate.type.UUIDType;
import java.util.UUID;
finally in your entity
终于在你的实体
@Id
@Override
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(name = "id", columnDefinition = "uuid")
public UUID getId() {
return id;
}