我正在試驗使用JPA生成索引。我已經知道JPA規範本身並不考慮生成索引的標準方法,但(某些)提供程序支持此功能。我正在測試新出生的Batoo(http://batoo.jp/),它對Hibernate和我對一個意外(對我的公司)行爲感到好奇。我們有2個類,首先定義沒有任何索引,並且我們在第二次定義兩個索引。當我們查看生成的表時,我們發現沒有實際創建索引。然後我們立即製作了這兩個類的精確副本,並將這些索引反映在數據庫中。這裏是重要的配置和類文件。
的JPA-beans.xml文件(對Hibernate)使用JPA創建MySQL索引(Hibernate和Batoo)
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans profile="hibernate" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<beans:import resource="classpath:spring/jpa-common.xml"/>
<beans:bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="jpaVendorAdapter">
<beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<beans:property name="database" value="MYSQL" />
<beans:property name="showSql" value="true" />
</beans:bean>
</beans:property>
<beans:property name="persistenceUnitName" value="jpa.sample" />
<beans:property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>
<beans:property name="jpaProperties">
<beans:props>
<beans:prop key="hibernate.enable_lazy_load_no_trans">true</beans:prop>
<beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<beans:bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<beans:property name="entityManagerFactory" ref="entityManagerFactory" />
<beans:property name="jpaDialect">
<beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</beans:property>
</beans:bean>
</beans:beans>
對於Batoo,我們只需將jpaVendorAdapter改變我們的自定義一個與jpaProperties映射,以使用由Batoo提供的特性。
的註解的Java類:
地址(在@Table註釋的uniqueConstraints是當表上的數據庫已經存在添加)和CopyOfAddress(在註解@Table立即那裏uniqueConstraints)。省略了setter和getter。
@Entity
@Table(uniqueConstraints={
@UniqueConstraint(name="uniqueAddress", columnNames={
"zipCode", "street", "number", "city", "country"
})
})
public class Address extends BaseEntity
{
private String zipCode;
private String street;
private String number;
private String city;
private String country;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
Long id;
@ManyToOne(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
private User user;
...
}
用戶和CopyOfUser
@Entity
public class User extends BaseEntity
{
@Column(unique=true)
private String username;
private String fullName;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
...
}
我們預計該數據庫中創建的表是相同的,但在這裏使用mysqldump獲得轉儲(只是有關創建表的語句) :
CREATE TABLE `Address` (
`zipCode` varchar(255) DEFAULT NULL,
`street` varchar(255) DEFAULT NULL,
`user_id` bigint(20) DEFAULT NULL,
`number` varchar(255) DEFAULT NULL,
`country` varchar(255) DEFAULT NULL,
`city` varchar(255) DEFAULT NULL,
`id` bigint(20) DEFAULT NULL,
KEY `FK_A2CD7CE3` (`user_id`),
CONSTRAINT `FK_A2CD7CE3` FOREIGN KEY (`user_id`) REFERENCES `User` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `CopyOfAddress` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`city` varchar(255) DEFAULT NULL,
`country` varchar(255) DEFAULT NULL,
`number` varchar(255) DEFAULT NULL,
`street` varchar(255) DEFAULT NULL,
`zipCode` varchar(255) DEFAULT NULL,
`user_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `zipCode` (`zipCode`,`street`,`number`,`city`,`country`),
KEY `FKA0BC6A08E9A4D67F` (`user_id`),
CONSTRAINT `FKA0BC6A08E9A4D67F` FOREIGN KEY (`user_id`) REFERENCES `User` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `User` (
`id` bigint(20) NOT NULL DEFAULT '0',
`username` varchar(255) DEFAULT NULL,
`fullName` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS `CopyOfUser`;
CREATE TABLE `CopyOfUser` (
`id` bigint(20) NOT NULL DEFAULT '0',
`username` varchar(255) DEFAULT NULL,
`fullName` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
正如你所看到的,在User和Address中都沒有索引被創建,而它們是完全相同的。有誰知道爲什麼?而且,作爲一個側面問題,是否有人知道爲什麼我們爲CopyOfAddress中的索引提供的名稱不被考慮?
編輯
如果它可以幫助,我可以加我使用Hibernate的4.1.7.Final和Batoo 2.0.1.0-RTM。
我的猜測是,當表已經創建並且索引必須被添加時,使用JPA提供者(至少我們嘗試過的兩種)是不可能的,因爲他們不知道如何處理現有數據,所以(也許)索引創建功能僅在創建時可用,而不能在表格的變更中使用...這可能嗎? – ThanksForAllTheFish