我正在使用 Oracle Spatial,并且有一个包含 SDO_GEOMETRY 字段的表。
该表映射到 JPA 实体。我希望将 SDO_GEOMETRY 字段映射到 java oracle.spatial.geometry.JGeometry
类型。
我想我应该使用 JPA Converter以及与java.sql.Struct
(或者oracle.sql.STRUCT
)之间的转换。
问题是 JGeometry 方法转换为 Struct,JGeometry.storeJS(Connection conn, JGeometry geom) ,想要 jdbc 连接作为参数。
spring EntityManagerFactory
配置了持久化单元名称,持久化单元包含数据源jndi名称,数据源定义在tomcat中,作为连接池。
知道如何在转换器中获取连接
吗?
这就是我想要实现的目标:
@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(*) 获取 if)
- 将该数据源注入(inject)到 Spring 助手中,以构建
EntityManagerFactory
(如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)!只要您获得 Connection
通过DataSourceUtils.getConnection(javax.sql.DataSource)
编辑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/