gpt4 book ai didi

java - 如何访问 JPA 转换器中的 jdbc 连接?

转载 作者:行者123 更新时间:2023-11-30 09:05:58 28 4
gpt4 key购买 nike

我正在使用 Oracle Spatial,并且我有一个包含 SDO_GEOMETRY 字段的表。该表映射到 JPA 实体。我想将 SDO_GEOMETRY 字段映射到 java oracle.spatial.geometry.JGeometry 类型。

我想我应该使用 JPA Converter并与 java.sql.Struct(或者 oracle.sql.STRUCT)相互转换。

问题是转换为 Struct 的 JGeometry 方法,JGeometry.storeJS(Connection conn, JGeometry geom) , 需要 jdbc 连接作为参数。

spring EntityManagerFactory配置了持久化单元名称,持久化单元包含数据源jndi名称,数据源定义在tomcat中,作为连接池。

关于如何在转换器中获取 Connection 有什么想法吗?

这是我想要实现的:

@Converter(autoApply = true)
public class GeometryConverter implements AttributeConverter<JGeometry, Struct> {

@Override
public Struct convertToDatabaseColumn(JGeometry geometry) {
// How to get this connection ?
return JGeometry.storeJS(connection, geometry);
}

@Override
public JGeometry convertToEntityAttribute(Struct struct) {
try {
return JGeometry.loadJS(struct);
} catch (SQLException e) {
throw new RuntimeException("Failed to convert geometry", e);
}
}
}

我正在使用 Spring 4、spring-data-jpa 1.6、Hibernate 4、Tomcat 8、Oracle 12c。

更新了更多信息:

Spring 配置:

@Configuration
@EnableJpaRepositories("com.package.repository")
@EnableTransactionManagement
@ComponentScan("com.package")
public class SpringConfig {

@Bean(name = "entityManagerFactory", destroyMethod = "destroy")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setPersistenceUnitName("persistence-unit");
return emf;
}

@Bean(name = "transactionManager")
public JpaTransactionManager getTransactionManager() {
return new JpaTransactionManager();
}
}

最佳答案

如果你使用 spring,并且你需要同时使用 JPA 和 JDBC,你应该:

  • 构造一个数据源 bean 并在那里建立连接池(或者从 jndi(*) 获取)
  • 将该数据源注入(inject)到用于构建 EntityManagerFactory 的 spring 助手中(例如 LocalContainerEntityManagerFactoryBean)
  • 将该数据源注入(inject)到您想要直接执行 JDBC 的任何 bean 中

这样您就可以将 JPA 用于您的普通 DAO,并且仍然可以在特殊部分访问 JDBC - 而不会太依赖于您的 JPA 提供程序的内部。

编辑:

(*) 如果您的数据源是由 jndi 名称定义的,那么一切都很好。将其公开为一个 bean ( ref )

如果使用 Spring 的基于 XML 架构的配置,请像这样在 Spring 上下文中设置:

<xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.2.xsd">
...
<jee:jndi-lookup id="dbDataSource"
jndi-name="jdbc/DatabaseName"
expected-type="javax.sql.DataSource" />

或者,使用像这样的简单 bean 配置进行设置:

<bean id="dbDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/DatabaseName"/>
</bean>

当您使用 JpaTransactionManager 时,不会有任何问题,因为如 spring javadoc 中所述 此事务管理器还支持事务内的直接数据源访问(即使用相同数据源的纯 JDBC 代码)。这允许混合访问 JPA 的服务和使用普通 JDBC 的服务(不知道 JPA)! 如果您通过 DataSourceUtils.getConnection(javax.sql.数据源)

编辑2:

好的,现在唯一的问题是如何从非 bean 对象访问单例 bean。解决它的一个简单方法是使用静态方法创建一个holder 单例 bean。

@Bean
public class DataSourceHolder implements InitializingBean {
private DataSource dataSource;

private static DataSourceHolder instance;

public static DataSource getDataSource() {
return instance.dataSource;
}

@Autowired
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public void afterPropertiesSet() throws Exception {
DataSourceHolder.instance = this;
}
}

然后在任何对象中,无论是不是bean,你都可以使用

DataSource ds = DataSourceHolder.getDataSource();
Connection con = DataSourceUtils.getConnection(ds);

关于java - 如何访问 JPA 转换器中的 jdbc 连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24649867/

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