मैं हाइबरनेट/जेपीए में सरणी से निपटने के लिए यूजरटाइप को लागू करने वाली कक्षा लिखने की कोशिश कर रहा हूं। मैंने समाधान बनाने के लिए निम्नलिखित पोस्ट mapping a postgres array with hibernate और Hibernate/JPA/HSQL : How to create a Dialect mapping for User Type ARRAY का उपयोग किया लेकिन मैं इसे काम नहीं कर सकता। मैंने इसका परीक्षण करने के लिए बस एक नया स्प्रिंग रू प्रोजेक्ट बनाया है।हाइबरनेट और पोस्टग्रेएसक्यूएल में उपयोगकर्ता टाइप के साथ ऐरे -> मैपिंग एक्सेप्शन
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<!-- <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/> -->
<property name="hibernate.dialect" value="test.PostgreSQLDialectArray"/>
<!-- value="create" to build a new database on each run; value="update" to modify an existing database; value="create-drop" means the same as "create" but also drops tables when Hibernate closes; value="validate" makes no changes to the database -->
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"/>
<property name="hibernate.connection.charSet" value="UTF-8"/>
<!-- Uncomment the following two properties for JBoss only -->
<!-- property name="hibernate.validator.apply_to_ddl" value="false" /-->
<!-- property name="hibernate.validator.autoregister_listeners" value="false" /-->
</properties>
</persistence-unit>
</persistence>
TestArray.java
package test;
import java.math.BigInteger;
import java.security.SecureRandom;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.roo.addon.javabean.RooJavaBean;
import org.springframework.roo.addon.serializable.RooSerializable;
import org.springframework.roo.addon.tostring.RooToString;
@RooJavaBean
@RooToString
@RooSerializable
public class TestArray {
private static final long serialVersionUID = 1L;
private SecureRandom random = new SecureRandom();
public String nextSessionId()
{
return new BigInteger(130, random).toString(32);
}
public static void main(String[] args) {
ApplicationContext context;
context = new ClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");
int[] array = new int[1428];
TestArray test = new TestArray();
Blabla blabla = new Blabla();
int nb = 1428;
for(int i = 0 ; i < nb ; i++)
array[i] = test.random.nextInt();
// blabla.setTest(array);
// blabla.persist();
// System.out.println(Arrays.toString(blabla.getTest()));
System.out.println(java.sql.Types.ARRAY);
System.out.println("Done");
}
}
Blabla.java
persistence.xml: यहाँ विभिन्न फ़ाइलें (सभी जावा वर्गों पैकेज परीक्षण में स्थित हैं) कर रहे हैं
package test; import org.hibernate.annotations.Type; import org.springframework.roo.addon.entity.RooEntity; import org.springframework.roo.addon.javabean.RooJavaBean; import org.springframework.roo.addon.tostring.RooToString; @RooJavaBean @RooToString @RooEntity public class Blabla { @Type(type = "test.IntArrayUserType") private int[] array; }
PostgreSQLDialectArray
package test; import java.sql.Types; public class PostgreSQLDialectArray extends org.hibernate.dialect.PostgreSQLDialect{ public PostgreSQLDialectArray() { super(); registerHibernateType(Types.ARRAY, "array"); } }
IntArrayUserType.java (mapping a postgres array with hibernate की तुलना में मूलतः एक ही)
package test; import java.io.Serializable; import java.sql.Array; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.hibernate.HibernateException; import org.hibernate.usertype.UserType; public class IntArrayUserType implements UserType { protected static final int SQLTYPE = java.sql.Types.ARRAY; private int[] toPrimitive(Integer[] array){ int[] a = new int[array.length]; for(int i = 0 ; i < array.length ; i++) a[i] = array[i]; return a; } private Integer[] toObject(int[] array){ Integer[] a = new Integer[array.length]; for(int i = 0 ; i < array.length ; i++) a[i] = array[i]; return a; } @Override public Object nullSafeGet(final ResultSet rs, final String[] names, final Object owner) throws HibernateException, SQLException { Array array = rs.getArray(names[0]); Integer[] javaArray = (Integer[]) array.getArray(); return toPrimitive(javaArray); } @Override public void nullSafeSet(final PreparedStatement statement, final Object object, final int i) throws HibernateException, SQLException { System.out.println("test null safe set..."); Connection connection = statement.getConnection(); int[] castObject = (int[]) object; Integer[] integers = toObject(castObject); Array array = connection.createArrayOf("integer", integers); statement.setArray(i, array); System.out.println("test null safe set..."); } @Override public Object assemble(final Serializable cached, final Object owner) throws HibernateException { return cached; } @Override public Object deepCopy(final Object o) throws HibernateException { return o == null ? null : ((int[]) o).clone(); } @Override public Serializable disassemble(final Object o) throws HibernateException { return (Serializable) o; } @Override public boolean equals(final Object x, final Object y) throws HibernateException { return x == null ? y == null : x.equals(y); } @Override public int hashCode(final Object o) throws HibernateException { return o == null ? 0 : o.hashCode(); } @Override public boolean isMutable() { return false; } @Override public Object replace(final Object original, final Object target, final Object owner) throws HibernateException { return original; } @Override public Class<int[]> returnedClass() { return int[].class; } @Override public int[] sqlTypes() { return new int[] { SQLTYPE }; } }
और अब स्टैकट्रेस:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [META-INF/spring/applicationContext.xml]: Cannot resolve reference to bean 'entityManagerFactory' while setting bean property 'entityManagerFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [META-INF/spring/applicationContext.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: persistenceUnit] Unable to build EntityManagerFactory
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1325)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1086)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at test.TestArray.main(TestArray.java:29)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [META-INF/spring/applicationContext.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: persistenceUnit] Unable to build EntityManagerFactory
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1420)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322)
... 15 more
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: persistenceUnit] Unable to build EntityManagerFactory
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:915)
at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:74)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:225)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:308)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
... 22 more
Caused by: org.hibernate.MappingException: No Dialect mapping for JDBC type: 2003
at org.hibernate.dialect.TypeNames.get(TypeNames.java:77)
at org.hibernate.dialect.TypeNames.get(TypeNames.java:100)
at org.hibernate.dialect.Dialect.getTypeName(Dialect.java:296)
at org.hibernate.mapping.Column.getSqlType(Column.java:208)
at org.hibernate.mapping.Table.sqlCreateString(Table.java:418)
at org.hibernate.cfg.Configuration.generateSchemaCreationScript(Configuration.java:1099)
at org.hibernate.tool.hbm2ddl.SchemaExport.<init>(SchemaExport.java:106)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:372)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1872)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:906)
... 27 more
तो मुझे लगता है कि बोली अनुमान जो मैंने बनाया है वह बिल्कुल या नहीं है गलत लेकिन मुझे नहीं पता क्यों। मुझे लगता है कि @ टाइप एनोटेशन मैपिंग करना चाहिए लेकिन मैंने कुछ टैग देखे हैं लेकिन मुझे नहीं पता कि उन्हें इस उदाहरण में क्या चाहिए और यदि वे हैं, तो मुझे कहां था? यह दो दिन हो गया है कि मैं इस समस्या से फंस गया हूं और मैं निराश हो रहा हूं। क्या आप इस कार्यक्रम को डीबग करने में मेरी मदद कर सकते हैं? कृप्या। अग्रिम में आपका बहुत बहुत धन्यवाद।
संपादित करें 0:
persistence.xml फ़ाइल सही बोली लेकिन समारोह getTypeName (2003) registerHibernateType (Types.ARRAY, "सरणी") करने के बाद ऊपर त्रुटियों फेंकता है खोजने के लिए लग रहे हैं। बीटीडब्लू, मैं हाइबरनेट 3.6.4 का उपयोग कर रहा हूं। फाइनल और पोस्टग्रेस्क्ल 8.4-702.jdbc3।
संपादित करें 1:
registerColumnType(Types.ARRAY, "integer[$l]");
जो आंशिक रूप से समस्या को हल करने लगता है:
मैं PostgreSQLDialectArray निर्माता में निम्न पंक्ति गयी।
2013-01-09 11:14:30,281 [main] ERROR org.hibernate.tool.hbm2ddl.SchemaExport - Unsuccessful: create table blabla (id int8 not null, array int[255], name varchar(255), test int4 not null, version int4, primary key (id))
2013-01-09 11:14:30,282 [main] ERROR org.hibernate.tool.hbm2ddl.SchemaExport - ERREUR: erreur de syntaxe sur ou près de « array »
Position: 40
जाहिर है, हाइबरनेट अभी भी उस में एक सरणी के साथ एक तालिका बनाने के लिए कैसे पता नहीं है ...
संपादित करें 2: हालांकि, अब मैं एक त्रुटि मिलती है
ऐसा लगता है कि postgresql इस तथ्य को पसंद नहीं आया कि मेरे कॉलम को "सरणी" कहा गया था। मैंने इसे बदल दिया और यह काम किया। तालिका को पूर्णांक की सरणी के साथ हाइबरनेट द्वारा बनाया गया है।
लेकिन मैं UserType कार्यान्वयन में किसी समस्या के कारण हाइबरनेट के साथ किसी भी सरणी को सहेज नहीं सकता। जाहिर है, सरणी का निर्माण createArrayOf के साथ विफल रहता है। मैं इस मामले पर कुछ थ्रेड पढ़ रहा हूं जो रैपर के बजाय अंतर्निहित कनेक्शन तक पहुंचने के लिए कह रहा है। मुझे लगता है कि मैं इसे जोड़ने के लिए एक नया धागा खोलने जा रहा हूं क्योंकि यह समस्या काफी अलग है।
स्टैकट्रेस:
Exception in thread "main" java.lang.AbstractMethodError: org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.createArrayOf(Ljava/lang/String;[Ljava/lang/Object;)Ljava/sql/Array;
at test.IntArrayUserType.nullSafeSet(IntArrayUserType.java:59)
at org.hibernate.type.CustomType.nullSafeSet(CustomType.java:140)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2184)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2430)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2874)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:76)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:467)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$afterReturning$org_springframework_transaction_aspectj_AbstractTransactionAspect$3$2a73e96c(AbstractTransactionAspect.aj:78)
at test.Blabla_Roo_Entity.ajc$interMethod$test_Blabla_Roo_Entity$test_Blabla$persist(Blabla_Roo_Entity.aj:56)
at test.Blabla.persist(Blabla.java:1)
at test.Blabla_Roo_Entity.ajc$interMethodDispatch1$test_Blabla_Roo_Entity$test_Blabla$persist(Blabla_Roo_Entity.aj)
at test.TestArray.main(TestArray.java:39)
संपादित करें 3:
अंत में, निम्न संशोधन के बाद, पूर्णांक सरणियों के लिए प्रयोक्ता प्रकार काम करता है:
applicationContext में इस लाइन में जोड़ें। xml में:
<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
....
<property name="accessToUnderlyingConnectionAllowed" value="true" />
</bean>
IntArrayUserType
से nullSafeSet संशोधित@Override public void nullSafeSet(final PreparedStatement statement, final Object object, final int i) throws HibernateException, SQLException { Connection connection = statement.getConnection(); int[] castObject = (int[]) object; Integer[] integers = toObject(castObject); Connection conn = ((DelegatingConnection) connection).getInnermostDelegate(); Array array = conn.createArrayOf("integer", integers); statement.setArray(i, array); }
लेकिन वहां अभी भी एक समस्या है जब तालिका blabla से सभी प्रविष्टियों हो रही है: फ़ंक्शन findAllBlablas ठीक से काम नहीं करता है और केवल लौटाता है पहली प्रविष्टि ...
संपादित 4:
वास्तव में, यह महान काम किया लेकिन ग्रहण सांत्वना सभी डेटा मुद्रित करने के लिए सक्षम नहीं था। बस इतना ही!
[हाइबरनेट के साथ एक postgres सरणी मानचित्रण] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/1647583/mapping-a-postgres-array-with-hibernate) – borchvm