试图在 Oracle 中存储时,Hibernate 无法为 AppSensor 实体生成 ID
Hibernate cannot generate IDs for AppSensor Entites while trying to store in Oracle
我正在尝试将 OWASP AppSensor 2.3.2 服务器设置为 Spring Boot 1.5.6 项目,该项目使用 JPA2 存储组件和 Oracle 12c 数据库。
到目前为止,我已经按照 AppSensor 指南设法在本地将服务器 运行 作为 Spring 启动应用程序获取。事件可以发送到服务器,也可以通过 application.properties 配置中的 spring.jpa.hibernate.ddl-auto 属性 自动创建数据库模式。
当服务器接收到事件并尝试存储它时,就会出现问题。显然,AppSensor 实体使用映射到整数列的字符串 ID。但是 Hibernate 不能自动生成 ID。启用 Hibernate 日志记录后,每次服务器收到事件时都会给出以下输出:
10:54:21.270 [http-nio-8085-exec-6] WARN o.o.a.s.j.Jpa2EventStore - Security event IE1 triggered by user: 127.0.0.2
- Hibernate: select hibernate_sequence.nextval from dual
10:54:21.270 [http-nio-8085-exec-6] ERROR o.a.c.c.C.[.[.[.[.o.a.r.AppSensorApplication] - Servlet.service() for servlet [org.owasp.appsensor.rest.AppSensorApplication] in context with path [] threw exception [org.springframework.orm.jpa.JpaSystemException: Unknown integral data type for ids : java.lang.String; nested exception is org.hibernate.id.IdentifierGenerationException: Unknown integral data type for ids : java.lang.String] with root cause
- org.hibernate.id.IdentifierGenerationException: Unknown integral data type for ids : java.lang.String
at org.hibernate.id.IdentifierGeneratorHelper.getIntegralDataTypeHolder(IdentifierGeneratorHelper.java:204)
at org.hibernate.id.SequenceGenerator.buildHolder(SequenceGenerator.java:144)
at org.hibernate.id.SequenceGenerator.generateHolder(SequenceGenerator.java:119)
at org.hibernate.id.SequenceGenerator.generate(SequenceGenerator.java:109)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:101)
at org.hibernate.jpa.event.internal.core.JpaMergeEventListener.saveWithGeneratedId(JpaMergeEventListener.java:56)
at org.hibernate.event.internal.DefaultMergeEventListener.saveTransientEntity(DefaultMergeEventListener.java:255)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:235)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:173)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:850)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:832)
at org.hibernate.engine.spi.CascadingActions.cascade(CascadingActions.java:260)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:398)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:162)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:111)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:425)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:232)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:173)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:69)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:840)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:822)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:827)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1161)
at sun.reflect.GeneratedMethodAccessor39.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298)
at com.sun.proxy.$Proxy85.merge(Unknown Source)
at org.owasp.appsensor.storage.jpa2.dao.EventRepository.save(EventRepository.java:41)
at org.owasp.appsensor.storage.jpa2.dao.EventRepository$$FastClassBySpringCGLIB$$a4c567f9.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at org.owasp.appsensor.storage.jpa2.dao.EventRepository$$EnhancerBySpringCGLIB$cbe7d38.save(<generated>)
at org.owasp.appsensor.storage.jpa2.Jpa2EventStore.addEvent(Jpa2EventStore.java:43)
at org.owasp.appsensor.handler.RestRequestHandler.addEvent(RestRequestHandler.java:69)
at sun.reflect.GeneratedMethodAccessor36.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.invoke(ResourceMethodInvocationHandlerFactory.java:81)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.run(AbstractJavaResourceMethodDispatcher.java:144)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$VoidOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:143)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime.run(ServerRuntime.java:326)
at org.glassfish.jersey.internal.Errors.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
问题是我无法真正更改实体。有什么方法可以告诉 Hibernate 如何生成这些 ID 而不必更改实体的代码,或者我的服务器是否存在其他问题?
这是Spring Boot Main class 如果有帮助的话:
@Configuration
@EnableAutoConfiguration
@ComponentScan(value="org.owasp.appsensor", excludeFilters = @ComponentScan.Filter(value = AppSensorClient.class, type = FilterType.ASSIGNABLE_TYPE))
public class AppSensorBootApplication {
public static void main(String[] args) {
SpringApplication.run(AppSensorBootApplication.class, args);
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.inet.appsensor</groupId>
<artifactId>appsensor-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>appsensor-ws-rest-server-boot</name>
<description>Spring Boot executable jar of appsensor rest server</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<appsensor.version>2.3.2</appsensor.version>
<docker.image.prefix>appsensor</docker.image.prefix>
</properties>
<dependencies>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-ws-rest-server</artifactId>
<version>${appsensor.version}</version>
<exclusions>
<exclusion>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
</exclusion>
<exclusion>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</exclusion>
<exclusion>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</exclusion>
<exclusion>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-inmemory</artifactId>
</exclusion>
<exclusion>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
</exclusion>
<exclusion>
<groupId>org.glassfish.jersey.bundles.repackaged</groupId>
<artifactId>jersey-guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-storage-jpa2</artifactId>
<version>${appsensor.version}</version>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-analysis-reference</artifactId>
<version>${appsensor.version}</version>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-reporting-simple-logging</artifactId>
<version>${appsensor.version}</version>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-access-control-reference</artifactId>
<version>${appsensor.version}</version>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-configuration-stax</artifactId>
<version>${appsensor.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.2.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<requiresUnpack>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-ws-rest-server</artifactId>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-core</artifactId>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-storage-in-memory</artifactId>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-analysis-reference</artifactId>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-reporting-simple-logging</artifactId>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-access-control-reference</artifactId>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-configuration-stax</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
</requiresUnpack>
</configuration>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.2.3</version>
<configuration>
<imageName>${docker.image.prefix}/${project.artifactId}</imageName>
<dockerDirectory>.</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
</project>
和 application.properties。请注意,我还必须更改命名策略,因为它试图创建像 "USER":
这样的表
server.port=8085
logging.level.org.springframework: INFO
logging.level.org.hibernate: INFO
spring.datasource.url=jdbc:oracle:thin:@hidden
spring.datasource.username=username
spring.datasource.password=password
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect
spring.jpa.properties.hibernate.physical_naming_strategy=org.owasp.appsensor.naming.PrefixNamingStrategy
spring.jpa.show-sql = true
这是 AppSensor 实体之一的示例(我无法更改):
@Entity
public class Event implements IAppsensorEntity {
@Id
@Column(columnDefinition = "integer")
@GeneratedValue
private String id;
private static final long serialVersionUID = -3235111340901139594L;
/** User who triggered the event, could be anonymous user */
@ManyToOne(cascade = CascadeType.ALL)
private User user;
/** Detection Point that was triggered */
@ManyToOne(cascade = CascadeType.ALL)
private DetectionPoint detectionPoint;
/** When the event occurred */
@Column
private String timestamp;
/**
* Identifier label for the system that detected the event.
* This will be either the client application, or possibly an external
* detection system, such as syslog, a WAF, network IDS, etc. */
@ManyToOne(cascade = CascadeType.ALL)
private DetectionSystem detectionSystem;
/**
* The resource being requested when the event was triggered, which can be used
* later to block requests to a given function.
*/
@ManyToOne(cascade = CascadeType.ALL)
private Resource resource;
/** Represent extra metadata, anything client wants to send */
@ElementCollection
@OneToMany(cascade = CascadeType.ALL)
private Collection<KeyValuePair> metadata = new ArrayList<>();
public Event () {}
public Event (User user, DetectionPoint detectionPoint, DetectionSystem detectionSystem) {
this(user, detectionPoint, DateUtils.getCurrentTimestampAsString(), detectionSystem);
}
public Event (User user, DetectionPoint detectionPoint, String timestamp, DetectionSystem detectionSystem) {
setUser(user);
setDetectionPoint(detectionPoint);
setTimestamp(timestamp);
setDetectionSystem(detectionSystem);
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
...
}
我通过使用 orm.xml 覆盖注释并基本上告诉 Hibernate 让数据库使用
生成 ID 解决了这个问题
<generated-value strategy="IDENTITY" />
结合序列和触发器。
我认为您只需要使用字符串作为 Id。
因此,在您的实体 class 中,您只需要使用 @Id 进行注释并且 不要 使用 @ GeneratedValue,因为@GeneratedValue注解默认不支持字符串。
您可以在@Id 注释之后使用@Column(length = 5) 注释,以获取数据库中的VARCHAR(5) 类型等等。
(我建议你使用这个带有给定长度的@Column注解,因为没有它,有时会产生错误)
接下来重要的是:您必须从数据库中删除 early-created table 并重新运行 spring 引导应用程序,否则它会给出相同的错误您更改了代码。
(在 mySQL,
drop table *tableName*;
用于删除table。
我正在尝试将 OWASP AppSensor 2.3.2 服务器设置为 Spring Boot 1.5.6 项目,该项目使用 JPA2 存储组件和 Oracle 12c 数据库。 到目前为止,我已经按照 AppSensor 指南设法在本地将服务器 运行 作为 Spring 启动应用程序获取。事件可以发送到服务器,也可以通过 application.properties 配置中的 spring.jpa.hibernate.ddl-auto 属性 自动创建数据库模式。 当服务器接收到事件并尝试存储它时,就会出现问题。显然,AppSensor 实体使用映射到整数列的字符串 ID。但是 Hibernate 不能自动生成 ID。启用 Hibernate 日志记录后,每次服务器收到事件时都会给出以下输出:
10:54:21.270 [http-nio-8085-exec-6] WARN o.o.a.s.j.Jpa2EventStore - Security event IE1 triggered by user: 127.0.0.2
- Hibernate: select hibernate_sequence.nextval from dual
10:54:21.270 [http-nio-8085-exec-6] ERROR o.a.c.c.C.[.[.[.[.o.a.r.AppSensorApplication] - Servlet.service() for servlet [org.owasp.appsensor.rest.AppSensorApplication] in context with path [] threw exception [org.springframework.orm.jpa.JpaSystemException: Unknown integral data type for ids : java.lang.String; nested exception is org.hibernate.id.IdentifierGenerationException: Unknown integral data type for ids : java.lang.String] with root cause
- org.hibernate.id.IdentifierGenerationException: Unknown integral data type for ids : java.lang.String
at org.hibernate.id.IdentifierGeneratorHelper.getIntegralDataTypeHolder(IdentifierGeneratorHelper.java:204)
at org.hibernate.id.SequenceGenerator.buildHolder(SequenceGenerator.java:144)
at org.hibernate.id.SequenceGenerator.generateHolder(SequenceGenerator.java:119)
at org.hibernate.id.SequenceGenerator.generate(SequenceGenerator.java:109)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:101)
at org.hibernate.jpa.event.internal.core.JpaMergeEventListener.saveWithGeneratedId(JpaMergeEventListener.java:56)
at org.hibernate.event.internal.DefaultMergeEventListener.saveTransientEntity(DefaultMergeEventListener.java:255)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:235)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:173)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:850)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:832)
at org.hibernate.engine.spi.CascadingActions.cascade(CascadingActions.java:260)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:398)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:162)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:111)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:425)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:232)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:173)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:69)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:840)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:822)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:827)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1161)
at sun.reflect.GeneratedMethodAccessor39.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298)
at com.sun.proxy.$Proxy85.merge(Unknown Source)
at org.owasp.appsensor.storage.jpa2.dao.EventRepository.save(EventRepository.java:41)
at org.owasp.appsensor.storage.jpa2.dao.EventRepository$$FastClassBySpringCGLIB$$a4c567f9.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at org.owasp.appsensor.storage.jpa2.dao.EventRepository$$EnhancerBySpringCGLIB$cbe7d38.save(<generated>)
at org.owasp.appsensor.storage.jpa2.Jpa2EventStore.addEvent(Jpa2EventStore.java:43)
at org.owasp.appsensor.handler.RestRequestHandler.addEvent(RestRequestHandler.java:69)
at sun.reflect.GeneratedMethodAccessor36.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.invoke(ResourceMethodInvocationHandlerFactory.java:81)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.run(AbstractJavaResourceMethodDispatcher.java:144)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$VoidOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:143)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime.run(ServerRuntime.java:326)
at org.glassfish.jersey.internal.Errors.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
问题是我无法真正更改实体。有什么方法可以告诉 Hibernate 如何生成这些 ID 而不必更改实体的代码,或者我的服务器是否存在其他问题?
这是Spring Boot Main class 如果有帮助的话:
@Configuration
@EnableAutoConfiguration
@ComponentScan(value="org.owasp.appsensor", excludeFilters = @ComponentScan.Filter(value = AppSensorClient.class, type = FilterType.ASSIGNABLE_TYPE))
public class AppSensorBootApplication {
public static void main(String[] args) {
SpringApplication.run(AppSensorBootApplication.class, args);
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.inet.appsensor</groupId>
<artifactId>appsensor-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>appsensor-ws-rest-server-boot</name>
<description>Spring Boot executable jar of appsensor rest server</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<appsensor.version>2.3.2</appsensor.version>
<docker.image.prefix>appsensor</docker.image.prefix>
</properties>
<dependencies>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-ws-rest-server</artifactId>
<version>${appsensor.version}</version>
<exclusions>
<exclusion>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
</exclusion>
<exclusion>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</exclusion>
<exclusion>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</exclusion>
<exclusion>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-inmemory</artifactId>
</exclusion>
<exclusion>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
</exclusion>
<exclusion>
<groupId>org.glassfish.jersey.bundles.repackaged</groupId>
<artifactId>jersey-guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-storage-jpa2</artifactId>
<version>${appsensor.version}</version>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-analysis-reference</artifactId>
<version>${appsensor.version}</version>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-reporting-simple-logging</artifactId>
<version>${appsensor.version}</version>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-access-control-reference</artifactId>
<version>${appsensor.version}</version>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-configuration-stax</artifactId>
<version>${appsensor.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.2.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<requiresUnpack>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-ws-rest-server</artifactId>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-core</artifactId>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-storage-in-memory</artifactId>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-analysis-reference</artifactId>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-reporting-simple-logging</artifactId>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-access-control-reference</artifactId>
</dependency>
<dependency>
<groupId>org.owasp.appsensor</groupId>
<artifactId>appsensor-configuration-stax</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
</requiresUnpack>
</configuration>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.2.3</version>
<configuration>
<imageName>${docker.image.prefix}/${project.artifactId}</imageName>
<dockerDirectory>.</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
</project>
和 application.properties。请注意,我还必须更改命名策略,因为它试图创建像 "USER":
这样的表server.port=8085
logging.level.org.springframework: INFO
logging.level.org.hibernate: INFO
spring.datasource.url=jdbc:oracle:thin:@hidden
spring.datasource.username=username
spring.datasource.password=password
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect
spring.jpa.properties.hibernate.physical_naming_strategy=org.owasp.appsensor.naming.PrefixNamingStrategy
spring.jpa.show-sql = true
这是 AppSensor 实体之一的示例(我无法更改):
@Entity
public class Event implements IAppsensorEntity {
@Id
@Column(columnDefinition = "integer")
@GeneratedValue
private String id;
private static final long serialVersionUID = -3235111340901139594L;
/** User who triggered the event, could be anonymous user */
@ManyToOne(cascade = CascadeType.ALL)
private User user;
/** Detection Point that was triggered */
@ManyToOne(cascade = CascadeType.ALL)
private DetectionPoint detectionPoint;
/** When the event occurred */
@Column
private String timestamp;
/**
* Identifier label for the system that detected the event.
* This will be either the client application, or possibly an external
* detection system, such as syslog, a WAF, network IDS, etc. */
@ManyToOne(cascade = CascadeType.ALL)
private DetectionSystem detectionSystem;
/**
* The resource being requested when the event was triggered, which can be used
* later to block requests to a given function.
*/
@ManyToOne(cascade = CascadeType.ALL)
private Resource resource;
/** Represent extra metadata, anything client wants to send */
@ElementCollection
@OneToMany(cascade = CascadeType.ALL)
private Collection<KeyValuePair> metadata = new ArrayList<>();
public Event () {}
public Event (User user, DetectionPoint detectionPoint, DetectionSystem detectionSystem) {
this(user, detectionPoint, DateUtils.getCurrentTimestampAsString(), detectionSystem);
}
public Event (User user, DetectionPoint detectionPoint, String timestamp, DetectionSystem detectionSystem) {
setUser(user);
setDetectionPoint(detectionPoint);
setTimestamp(timestamp);
setDetectionSystem(detectionSystem);
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
...
}
我通过使用 orm.xml 覆盖注释并基本上告诉 Hibernate 让数据库使用
生成 ID 解决了这个问题<generated-value strategy="IDENTITY" />
结合序列和触发器。
我认为您只需要使用字符串作为 Id。 因此,在您的实体 class 中,您只需要使用 @Id 进行注释并且 不要 使用 @ GeneratedValue,因为@GeneratedValue注解默认不支持字符串。 您可以在@Id 注释之后使用@Column(length = 5) 注释,以获取数据库中的VARCHAR(5) 类型等等。 (我建议你使用这个带有给定长度的@Column注解,因为没有它,有时会产生错误)
接下来重要的是:您必须从数据库中删除 early-created table 并重新运行 spring 引导应用程序,否则它会给出相同的错误您更改了代码。
(在 mySQL,
drop table *tableName*;
用于删除table。