gpt4 book ai didi

java - (在 Hibernate 5.1.0 中)由 : java. lang.ClassNotFoundException 引起:无法加载请求的类:MyJsonType

转载 作者:行者123 更新时间:2023-12-02 11:34:30 25 4
gpt4 key购买 nike

我尝试实现一个使用“PostgreSQL 的 JSONB 数据类型与 Hibernate v5.1.0”的 Maven 项目,并使用名为“MyJsonType”的自定义用户类型作为“jsonb”数据类型。所以我没有得到与“MyJsonType”相关的其他需要配置的内容。我按照下面的文章尝试过。

但同样的概念适用于 JPA(使用 EntityManager 来持久化对象),但这里我使用了 HIBERNATE API

请检查最后一个代码块中的完整错误日志。

我还没有实现 MyJsonType.java、MyPostgreSQL94Dialect.java、package-info.java,这些都是已经定义的,并按照下面的文章从 git 获取它。

我使用以下链接来完成此示例项目:
https://www.thoughts-on-java.org/persist-postgresqls-jsonb-data-type-hibernate/

感谢任何帮助。

hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-5.0.dtd">

<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.connection.url">jdbc:postgresql://localhost:5433/sample_database</property>
<property name="hibernate.connection.username">postgres</property>
<property name="hibernate.connection.password">admin</property>
<property name="hibernate.connection.pool_size">10</property>
<property name="show_sql">true</property>
<property name="hibernate.dialect">com.code.model.MyPostgreSQL94Dialect</property>
<property name="hibernate.current_session_context_class">thread</property>

<mapping class="com.code.model.Address" />

</session-factory>
</hibernate-configuration>

地址.java

package com.code.model;
import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.Type;

@Entity
@Table(name = "address")
public class Address implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="emp_id", updatable = false, nullable = false)
private Long empId;

@Column(name="emp_Details")
@Type(type = "MyJsonType")
private MyJson empDetails;

public long getEmpId() {
return empId;
}

public void setEmpId(long empId) {
this.empId = empId;
}

public MyJson getEmpDetails() {
return empDetails;
}

public void setEmpDetails(MyJson empDetails) {
this.empDetails = empDetails;
}
}

MyJson.java

package com.code.model;

import java.io.Serializable;

public class MyJson implements Serializable {
private String details;

public String getDetails() {
return details;
}

public void setDetails(String details) {
this.details = details;
}
}

MyJsonType.java

package com.code.model;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.StringWriter;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;

import com.fasterxml.jackson.databind.ObjectMapper;

public class MyJsonType implements UserType {

@Override
public int[] sqlTypes() {
return new int[]{Types.JAVA_OBJECT};
}

@Override
public Class<MyJson> returnedClass() {
return MyJson.class;
}

@Override
public Object nullSafeGet(final ResultSet rs, final String[] names, final SessionImplementor session,
final Object owner) throws HibernateException, SQLException {
final String cellContent = rs.getString(names[0]);
if (cellContent == null) {
return null;
}
try {
final ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(cellContent.getBytes("UTF-8"), returnedClass());
} catch (final Exception ex) {
throw new RuntimeException("Failed to convert String to Invoice: " + ex.getMessage(), ex);
}
}

@Override
public void nullSafeSet(final PreparedStatement ps, final Object value, final int idx,
final SessionImplementor session) throws HibernateException, SQLException {
if (value == null) {
ps.setNull(idx, Types.OTHER);
return;
}
try {
final ObjectMapper mapper = new ObjectMapper();
final StringWriter w = new StringWriter();
mapper.writeValue(w, value);
w.flush();
ps.setObject(idx, w.toString(), Types.OTHER);
} catch (final Exception ex) {
throw new RuntimeException("Failed to convert Invoice to String: " + ex.getMessage(), ex);
}
}

@Override
public Object deepCopy(final Object value) throws HibernateException {
try {
// use serialization to create a deep copy
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(value);
oos.flush();
oos.close();
bos.close();

ByteArrayInputStream bais = new ByteArrayInputStream(bos.toByteArray());
return new ObjectInputStream(bais).readObject();
} catch (ClassNotFoundException | IOException ex) {
throw new HibernateException(ex);
}
}

@Override
public boolean isMutable() {
return true;
}

@Override
public Serializable disassemble(final Object value) throws HibernateException {
return (Serializable) this.deepCopy(value);
}

@Override
public Object assemble(final Serializable cached, final Object owner) throws HibernateException {
return this.deepCopy(cached);
}

@Override
public Object replace(final Object original, final Object target, final Object owner) throws HibernateException {
return this.deepCopy(original);
}

@Override
public boolean equals(final Object obj1, final Object obj2) throws HibernateException {
if (obj1 == null) {
return obj2 == null;
}
return obj1.equals(obj2);
}

@Override
public int hashCode(final Object obj) throws HibernateException {
return obj.hashCode();
}
}

MyPostgreSQL94Dialect.java

package com.code.model;

import java.sql.Types;

import org.hibernate.dialect.PostgreSQL94Dialect;

public class MyPostgreSQL94Dialect extends PostgreSQL94Dialect {
public MyPostgreSQL94Dialect() {
this.registerColumnType(Types.JAVA_OBJECT, "jsonb");
}
}

package-info.java

@org.hibernate.annotations.TypeDef(name = "MyJsonType", typeClass = com.comcast.model.MyJsonType.class)

package com.comcast.model;

CreateData.java(主类)

package com.code;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import com.code.model.Address;
import com.code.model.MyJson;

public class CreateData {
static SessionFactory sessFact;
static Session session;
static Transaction tr;

public static void main(String[] args) throws Exception {
init();
CreateData cd = new CreateData();
cd.insert();
}

public static void init() {
sessFact = HibernateUtil.getSessionFactory();
session = sessFact.getCurrentSession();
tr = session.beginTransaction();
}

public void insert() {
String json = "{" + "\"city\" : \"Lawrence\"," + "\"state\" : \"432 Essentric exmark street\"," + "\"zipcode\" : \"11111\"}";

MyJson j = new MyJson();
j.setDetails(json);

Address add = new Address();
add.setEmpDetails(j);

session.save(add);
tr.commit();
System.out.println("Successfully inserted");
sessFact.close();
}
}

错误:

Mar 01, 2018 7:30:33 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.1.0.Final}
Mar 01, 2018 7:30:33 PM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
Mar 01, 2018 7:30:33 PM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
Mar 01, 2018 7:30:33 PM org.hibernate.boot.jaxb.internal.stax.LocalXmlResourceResolver resolveEntity
WARN: HHH90000012: Recognized obsolete hibernate namespace http://hibernate.sourceforge.net/hibernate-configuration. Use namespace http://www.hibernate.org/dtd/hibernate-configuration instead. Support for obsolete DTD/XSD namespaces may be removed at any time.
Mar 01, 2018 7:30:33 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
Mar 01, 2018 7:30:33 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)
Mar 01, 2018 7:30:33 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001005: using driver [org.postgresql.Driver] at URL [jdbc:postgresql://localhost:5433/sample_database]
Mar 01, 2018 7:30:33 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001001: Connection properties: {user=postgres, password=****}
Mar 01, 2018 7:30:33 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001003: Autocommit mode: false
Mar 01, 2018 7:30:33 PM org.hibernate.engine.jdbc.connections.internal.PooledConnections <init>
INFO: HHH000115: Hibernate connection pool size: 10 (min=1)
Mar 01, 2018 7:30:34 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: com.comcast.model.MyPostgreSQL94Dialect
Mar 01, 2018 7:30:34 PM org.hibernate.engine.jdbc.env.internal.LobCreatorBuilderImpl useContextualLobCreation
INFO: HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
Mar 01, 2018 7:30:34 PM org.hibernate.type.BasicTypeRegistry register
INFO: HHH000270: Type registration [java.util.UUID] overrides previous : org.hibernate.type.UUIDBinaryType@6a2f6f80
Enitial SessionFactory creation failedorg.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [MyJsonType]
Exception in thread "main" java.lang.ExceptionInInitializerError
at com.comcast.HibernateUtil.<clinit>(HibernateUtil.java:30)
at com.comcast.CreateData.init(CreateData.java:29)
at com.comcast.CreateData.main(CreateData.java:21)
Caused by: org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [MyJsonType]
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:229)
at org.hibernate.boot.internal.ClassLoaderAccessImpl.classForName(ClassLoaderAccessImpl.java:62)
at org.hibernate.cfg.annotations.SimpleValueBinder.fillSimpleValue(SimpleValueBinder.java:521)
at org.hibernate.cfg.SetSimpleValueTypeSecondPass.doSecondPass(SetSimpleValueTypeSecondPass.java:25)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1621)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1579)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:418)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:87)
at com.comcast.HibernateUtil.<clinit>(HibernateUtil.java:24)
... 2 more
Caused by: java.lang.ClassNotFoundException: Could not load requested class : MyJsonType
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl$AggregatedClassLoader.findClass(ClassLoaderServiceImpl.java:217)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:226)
... 12 more

最佳答案

我自己的 UserType 也遇到了同样奇怪的错误。更有趣的是,仅当使用 Gradle 在命令行上执行我的测试时才会发生该错误,而在 IDE (IntelliJ) 中执行我的测试时不会发生该错误。因为这样,我认为这是某种错误。

我通过将 @TypeDef 注释从 package-info.java 文件直接移动到实体文件来解决这个问题:

@Entity
@Table(name = "address")
@TypeDef(name = "MyJsonType", typeClass = com.comcast.model.MyJsonType.class)
public class Address implements Serializable {
//...
}

关于java - (在 Hibernate 5.1.0 中)由 : java. lang.ClassNotFoundException 引起:无法加载请求的类:MyJsonType,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49053385/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com