我在 feedLocation 上收到一个字符串编码位置,并且我定义了一种方法来将字符串分割为三个坐标 x、y、z。
public class Feedback {
@Column(name = "feedback_id")
private @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="my_entity_seq_gen") Integer feedbackId;
@Column(name = "feed_date", columnDefinition= "TIMESTAMP WITH TIME ZONE DEFAULT clock_timestamp()")
private LocalDateTime feedDate;
@Column(name = "sens_code")
private String sensCode;
@Column(name = "feed_value")
private Double feedValue;
@Column(name = "location")
private String feedLocation;
@Transient
private Double longitude = coordinates("x");
@Transient
private Double latitude = coordinates("y");
@Transient
private Double altitude = coordinates("z");
}
Coorrdinates 方法获取的字符串坐标仍然为空,导致编译失败。
public Double coordinates(String coordinate){
String wkbString = feedLocation;
WKBReader reader = new WKBReader();
Geometry geometry;
try {
geometry = reader.read(Hex.decodeHex(wkbString.toCharArray()));
} catch (ParseException | DecoderException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
String geometryText = geometry.toString();
if (geometry.getGeometryType().equalsIgnoreCase("Point")) {
double latitude = geometry.getCoordinate().y;
double longitude = geometry.getCoordinate().x;
double altitude = geometry.getCoordinate().z;
switch (coordinate) {
case "x":
return longitude;
case "y":
return latitude;
case "z":
return altitude;
}
return null;
}
return null;
}
我希望在这三个坐标上获得正确的值,但是当我编译时出现错误,因为当类初始化时feedLocation仍然为空。
堆栈跟踪:
Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)
at com.IOTProjectUI.Application.main(Application.java:26)
... 5 more
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
... 21 more
Caused by: org.hibernate.MappingException: Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister
at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:123)
at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:77)
at org.hibernate.metamodel.internal.MetamodelImpl.initialize(MetamodelImpl.java:181)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:319)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1498)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
... 25 more
Caused by: org.hibernate.InstantiationException: could not instantiate test object : com.IOTProjectUI.domain.Feedback
at org.hibernate.engine.internal.UnsavedValueFactory.instantiate(UnsavedValueFactory.java:43)
at org.hibernate.engine.internal.UnsavedValueFactory.getUnsavedIdentifierValue(UnsavedValueFactory.java:68)
at org.hibernate.tuple.PropertyFactory.buildIdentifierAttribute(PropertyFactory.java:65)
at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:142)
at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:613)
at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:126)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:96)
... 33 more
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
at org.hibernate.engine.internal.UnsavedValueFactory.instantiate(UnsavedValueFactory.java:40)
... 44 more
Caused by: java.lang.NullPointerException: Cannot invoke "String.toCharArray()" because "wkbString" is null
at com.IOTProjectUI.domain.Feedback.coordinates(Feedback.java:98)
at com.IOTProjectUI.domain.Feedback.<init>(Feedback.java:66)
... 50 more
为了解决您的问题,您应该将坐标的计算移至 getter 方法:
public class Feedback {
@Column(name = "feedback_id")
private @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="my_entity_seq_gen") Integer feedbackId;
@Column(name = "feed_date", columnDefinition= "TIMESTAMP WITH TIME ZONE DEFAULT clock_timestamp()")
private LocalDateTime feedDate;
@Column(name = "sens_code")
private String sensCode;
@Column(name = "feed_value")
private Double feedValue;
@Column(name = "location")
private String feedLocation;
public Double getLongitude() {
return coordinates("x");
}
public Double getLatitude() {
return coordinates("y");
}
public Double getAltitude() {
return coordinates("z");
}
}
这样,您将避免在对象初始化期间计算字段,而是在需要时计算它们。
请记住,每次使用此方法都会重新计算字段。
为了避免这种情况,您可以使用
@PostLoad
注释来代替:
public class Feedback {
@Column(name = "feedback_id")
private @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="my_entity_seq_gen") Integer feedbackId;
@Column(name = "feed_date", columnDefinition= "TIMESTAMP WITH TIME ZONE DEFAULT clock_timestamp()")
private LocalDateTime feedDate;
@Column(name = "sens_code")
private String sensCode;
@Column(name = "feed_value")
private Double feedValue;
@Column(name = "location")
private String feedLocation;
@Transient
private Double longitude;
@Transient
private Double latitude;
@Transient
private Double altitude;
@PostLoad
private void postLoad() {
this.longitude = coordinates("x");
this.latitude = coordinates("y");
this.altitude = coordinates("z");
}
}
有关更多详细信息,请查看这篇优秀的博客文章:https://vladmihalcea.com/how-to-map-calculated-properties-with-jpa-and-hibernate-formula-annotation/