一、结构

二、配置文件约定

The JPA provider automatically picks up this descriptor if you place it in a META-INF /orm.xml file on the classpath of the persistence unit. If you prefer to use a different name or several files, you’ll have to change the configuration of the persistence unit in your META-INF /persistence.xml file:

If you include the <xml-mapping-metadata-complete> element, the JPA provider ignores all annotations on your domain model classes in this persistence unit and relies only on the mappings as defined in the XML descriptor(s). You can (redundantly in this case) enable this on an entity level, with <metadata-complete="true"/> . If enabled, the JPA provider assumes that you mapped all attributes of the entity in XML and that it should ignore all annotations for this particular entity.

1.Mappings.xml

 <entity-mappings
version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm
http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd"> <!-- First, global metadata -->
<persistence-unit-metadata> <!-- Ignore all annotations, all mapping metadata in XML files -->
<xml-mapping-metadata-complete/> <!-- Some default settings -->
<persistence-unit-defaults>
<!--
Escape all SQL column/table/etc. names, e.g. if your SQL
names are actually keywords (a "USER" table for example)
-->
<delimited-identifiers/>
</persistence-unit-defaults> </persistence-unit-metadata> <entity class="org.jpwh.model.simple.Item" access="FIELD">
<attributes>
<id name="id">
<generated-value strategy="AUTO"/>
</id>
<basic name="name"/>
<basic name="auctionEnd">
<temporal>TIMESTAMP</temporal>
</basic>
<transient name="bids"/>
<transient name="category"/>
</attributes>
</entity> </entity-mappings>

2.MappingsOverride.xml

 <entity-mappings
version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm
http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd"> <entity class="org.jpwh.model.simple.Item">
<attributes>
<!-- Override the SQL column name -->
<basic name="name">
<column name="ITEM_NAME"/>
</basic>
</attributes>
</entity> </entity-mappings>

3.Queries.xml

 <entity-mappings
version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm
http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd"> <named-query name="findItems">
<query><![CDATA[
select i from Item i
]]></query>
</named-query> <named-query name="findItemsWithHints">
<query>select i from Item i</query>
<hint name="org.hibernate.comment" value="My Comment"/>
<hint name="org.hibernate.fetchSize" value="50"/>
<hint name="org.hibernate.readOnly" value="true"/>
<hint name="org.hibernate.timeout" value="60"/>
</named-query> </entity-mappings>

4.Native.hbm.xml

 <?xml version="1.0"?>
<!--
Metadata is declared inside a <code>&lt;hibernate-mapping&gt;</code> root element. Attributes such as
<code>package</code> name and <code>default-access</code> apply to all mappings in this file. You may include as many
entity class mappings as you like.
-->
<hibernate-mapping
xmlns="http://www.hibernate.org/xsd/orm/hbm"
package="org.jpwh.model.simple"
default-access="field"> <!-- An entity class mapping -->
<class name="Item">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<property name="auctionEnd" type="timestamp"/>
</class> <!-- Externalized queries -->
<query name="findItemsHibernate">select i from Item i</query> <!-- Auxiliary schema DDL -->
<database-object>
<create>create index ITEM_NAME_IDX on ITEM(NAME)</create>
<drop>drop index if exists ITEM_NAME_IDX</drop>
</database-object> </hibernate-mapping>

三、domain层

1.

 package org.jpwh.model.querying;

 import org.jpwh.model.Constants;

 import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal; @Entity
public class Bid { @Id
@GeneratedValue(generator = Constants.ID_GENERATOR)
protected Long id; @NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(foreignKey = @ForeignKey(name = "FK_BID_ITEM_ID"))
protected Item item; @ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(foreignKey = @ForeignKey(name = "FK_BID_BIDDER_ID"))
protected User bidder; @NotNull
protected BigDecimal amount; public Bid() {
} public Bid(Item item, User bidder, BigDecimal amount) {
this.item = item;
this.amount = amount;
this.bidder = bidder;
} public Item getItem() {
return item;
} public void setItem(Item item) {
this.item = item;
} public User getBidder() {
return bidder;
} public void setBidder(User bidder) {
this.bidder = bidder;
} public BigDecimal getAmount() {
return amount;
} public void setAmount(BigDecimal amount) {
this.amount = amount;
}
}

2.

 package org.jpwh.model.querying;

 import org.jpwh.model.Constants;

 import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashSet;
import java.util.Set; @NamedQueries({
@NamedQuery(
name = "findItemById",
query = "select i from Item i where i.id = :id"
)
,
@NamedQuery(
name = "findItemByName",
query = "select i from Item i where i.name like :name",
hints = {
@QueryHint(
name = org.hibernate.annotations.QueryHints.TIMEOUT_JPA,
value = "60000"),
@QueryHint(
name = org.hibernate.annotations.QueryHints.COMMENT,
value = "Custom SQL comment")
}
)
})
@SqlResultSetMappings({
@SqlResultSetMapping(
name = "ItemResult",
entities =
@EntityResult(
entityClass = Item.class,
fields = {
@FieldResult(name = "id", column = "ID"),
@FieldResult(name = "name", column = "EXTENDED_NAME"),
@FieldResult(name = "createdOn", column = "CREATEDON"),
@FieldResult(name = "auctionEnd", column = "AUCTIONEND"),
@FieldResult(name = "auctionType", column = "AUCTIONTYPE"),
@FieldResult(name = "approved", column = "APPROVED"),
@FieldResult(name = "buyNowPrice", column = "BUYNOWPRICE"),
@FieldResult(name = "seller", column = "SELLER_ID")
}
)
)
})
@Entity
public class Item { @Id
@GeneratedValue(generator = Constants.ID_GENERATOR)
protected Long id; @NotNull
protected String name; @NotNull
protected Date createdOn = new Date(); @NotNull
protected Date auctionEnd; @NotNull
@Enumerated(EnumType.STRING)
protected AuctionType auctionType = AuctionType.HIGHEST_BID; @NotNull
protected boolean approved = true; protected BigDecimal buyNowPrice; @ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(foreignKey = @ForeignKey(name = "FK_ITEM_SELLER_ID"))
protected User seller; @ManyToMany(mappedBy = "items")
protected Set<Category> categories = new HashSet<>(); @OneToMany(mappedBy = "item")
protected Set<Bid> bids = new HashSet<>(); @ElementCollection
@JoinColumn(foreignKey = @ForeignKey(name = "FK_ITEM_IMAGES_ITEM_ID"))
protected Set<Image> images = new HashSet<>(); public Item() {
} public Item(String name, Date auctionEnd, User seller) {
this.name = name;
this.auctionEnd = auctionEnd;
this.seller = seller;
} public Long getId() {
return id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Date getCreatedOn() {
return createdOn;
} public Date getAuctionEnd() {
return auctionEnd;
} public void setAuctionEnd(Date auctionEnd) {
this.auctionEnd = auctionEnd;
} public AuctionType getAuctionType() {
return auctionType;
} public void setAuctionType(AuctionType auctionType) {
this.auctionType = auctionType;
} public boolean isApproved() {
return approved;
} public void setApproved(boolean approved) {
this.approved = approved;
} public BigDecimal getBuyNowPrice() {
return buyNowPrice;
} public void setBuyNowPrice(BigDecimal buyNowPrice) {
this.buyNowPrice = buyNowPrice;
} public User getSeller() {
return seller;
} public void setSeller(User seller) {
this.seller = seller;
} public Set<Category> getCategories() {
return categories;
} public void setCategories(Set<Category> categories) {
this.categories = categories;
} public Set<Bid> getBids() {
return bids;
} public void setBids(Set<Bid> bids) {
this.bids = bids;
} public Set<Image> getImages() {
return images;
} public void setImages(Set<Image> images) {
this.images = images;
}
// ...
}

3.

 @org.hibernate.annotations.NamedQueries({
@org.hibernate.annotations.NamedQuery(
name = "findItemsOrderByName",
query = "select i from Item i order by i.name asc"
)
,
@org.hibernate.annotations.NamedQuery(
name = "findItemBuyNowPriceGreaterThan",
query = "select i from Item i where i.buyNowPrice > :price",
timeout = 60, // Seconds!
comment = "Custom SQL comment"
)
}) package org.jpwh.model.querying;

四、测试文件

1.

 package org.jpwh.test.simple;

 import org.jpwh.model.simple.Bid;
import org.jpwh.model.simple.Item;
import org.testng.annotations.Test; import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.Date;
import java.util.Locale;
import java.util.Set; import static org.testng.Assert.*; public class ModelOperations { @Test
public void linkBidAndItem() {
Item anItem = new Item();
Bid aBid = new Bid(); anItem.getBids().add(aBid);
aBid.setItem(anItem); assertEquals(anItem.getBids().size(), 1);
assertTrue(anItem.getBids().contains(aBid));
assertEquals(aBid.getItem(), anItem); // Again with convenience method
Bid secondBid = new Bid();
anItem.addBid(secondBid); assertEquals(2, anItem.getBids().size());
assertTrue(anItem.getBids().contains(secondBid));
assertEquals(anItem, secondBid.getItem());
} @Test
public void validateItem() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator(); Item item = new Item();
item.setName("Some Item");
item.setAuctionEnd(new Date()); Set<ConstraintViolation<Item>> violations = validator.validate(item); // We have one validation error, auction end date was not in the future!
assertEquals(1, violations.size()); ConstraintViolation<Item> violation = violations.iterator().next();
String failedPropertyName =
violation.getPropertyPath().iterator().next().getName(); assertEquals(failedPropertyName, "auctionEnd"); if (Locale.getDefault().getLanguage().equals("en"))
assertEquals(violation.getMessage(), "must be in the future");
} }

2.

 package org.jpwh.test.simple;

 import org.jpwh.env.JPATest;
import org.jpwh.model.simple.Item;
//import org.jpwh.model.simple.Item_;
import org.testng.annotations.Test; import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.Metamodel;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.Type;
import javax.transaction.UserTransaction;
import java.util.Date;
import java.util.List;
import java.util.Set; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse; public class AccessJPAMetamodel extends JPATest { @Override
public void configurePersistenceUnit() throws Exception {
configurePersistenceUnit("SimpleXMLCompletePU");
} @Test
public void accessDynamicMetamodel() throws Exception {
EntityManagerFactory entityManagerFactory = JPA.getEntityManagerFactory(); Metamodel mm = entityManagerFactory.getMetamodel(); Set<ManagedType<?>> managedTypes = mm.getManagedTypes();
assertEquals(managedTypes.size(), 1); ManagedType itemType = managedTypes.iterator().next();
assertEquals(
itemType.getPersistenceType(),
Type.PersistenceType.ENTITY
); SingularAttribute nameAttribute =
itemType.getSingularAttribute("name");
assertEquals(
nameAttribute.getJavaType(),
String.class
);
assertEquals(
nameAttribute.getPersistentAttributeType(),
Attribute.PersistentAttributeType.BASIC
);
assertFalse(
nameAttribute.isOptional() // NOT NULL
); SingularAttribute auctionEndAttribute =
itemType.getSingularAttribute("auctionEnd");
assertEquals(
auctionEndAttribute.getJavaType(),
Date.class
);
assertFalse(
auctionEndAttribute.isCollection()
);
assertFalse(
auctionEndAttribute.isAssociation()
);
} /* @Test
public void accessStaticMetamodel() throws Exception { SingularAttribute nameAttribute = Item_.name; assertEquals(
nameAttribute.getJavaType(),
String.class
);
}*/ @Test
public void queryStaticMetamodel() throws Exception {
UserTransaction tx = TM.getUserTransaction();
try {
tx.begin(); EntityManager entityManager = JPA.createEntityManager(); Item itemOne = new Item();
itemOne.setName("This is some item");
itemOne.setAuctionEnd(new Date(System.currentTimeMillis() + 100000));
entityManager.persist(itemOne); Item itemTwo = new Item();
itemTwo.setName("Another item");
itemTwo.setAuctionEnd(new Date(System.currentTimeMillis() + 100000)); entityManager.persist(itemTwo); tx.commit();
entityManager.close(); entityManager = JPA.createEntityManager();
tx.begin(); CriteriaBuilder cb = entityManager.getCriteriaBuilder(); // This query is the equivalent of "select i from Item i"
CriteriaQuery<Item> query = cb.createQuery(Item.class);
Root<Item> fromItem = query.from(Item.class);
query.select(fromItem); List<Item> items =
entityManager.createQuery(query)
.getResultList(); assertEquals(items.size(), 2); // "where i.name like :pattern"
Path<String> namePath = fromItem.get("name");
query.where(
cb.like(
namePath, // Has to be a Path<String> for like() operator!
cb.parameter(String.class, "pattern")
)
); items =
entityManager.createQuery(query)
.setParameter("pattern", "%some item%") // Wildcards!
.getResultList(); assertEquals(items.size(), 1);
assertEquals(items.iterator().next().getName(), "This is some item"); // query.where(
// cb.like(
// fromItem.get(Item_.name), // Static Item_ metamodel!
// cb.parameter(String.class, "pattern")
// )
// ); items =
entityManager.createQuery(query)
.setParameter("pattern", "%some item%") // Wildcard!
.getResultList(); assertEquals(items.size(), 1);
assertEquals(items.iterator().next().getName(), "This is some item"); tx.commit();
entityManager.close();
} finally {
TM.rollback();
}
} }

JavaPersistenceWithHibernate第二版笔记Getting started with ORM-002Domain层详解及M etaModel的更多相关文章

  1. JavaPersistenceWithHibernate第二版笔记-第四章-Mapping persistent classes-002identity详解

    一.简介 1.You now have three methods for distinguishing references:  Objects are identical if they occ ...

  2. JavaPersistenceWithHibernate第二版笔记-第四章-Mapping persistent classes-003映射实体时的可选操作(<delimited-identifiers/>、PhysicalNamingStrategy、PhysicalNamingStrategyStandardImpl、、、)

    一.自定义映射的表名 1. @Entity @Table(name = "USERS") public class User implements Serializable { / ...

  3. JavaPersistenceWithHibernate第二版笔记Getting started with ORM-001用JPA和Hibernate实现HellowWorld(JTA、Bitronix)

    一.结构 二.model层 1. package org.jpwh.model.helloworld; import javax.persistence.Entity; import javax.pe ...

  4. JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-006Mixing inheritance strategies(@SecondaryTable、@PrimaryKeyJoinColumn、<join fetch="select">)

    一.结构 For example, you can map a class hierarchy to a single table, but, for a particular subclass, s ...

  5. JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-003Table per concrete class with unions(@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)、<union-subclass>)

    一.代码 1. package org.jpwh.model.inheritance.tableperclass; import org.jpwh.model.Constants; import ja ...

  6. JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-002Table per concrete class with implicit polymorphism(@MappedSuperclass、@AttributeOverride)

    一.结构 二.代码 1. package org.jpwh.model.inheritance.mappedsuperclass; import javax.persistence.MappedSup ...

  7. JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-001Hibernate映射继承的方法

    There are four different strategies for representing an inheritance hierarchy: Use one table per co ...

  8. JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-007UserTypes的用法(@org.hibernate.annotations.Type、@org.hibernate.annotations.TypeDefs、CompositeUserType、DynamicParameterizedType、、、)

    一.结构 二.Hibernate支持的UserTypes接口  UserType —You can transform values by interacting with the plain JD ...

  9. JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-006类型转换器( @Converter(autoApply = true) 、type="converter:qualified.ConverterName" )

    一.结构 二.代码 1. package org.jpwh.model.advanced; import java.io.Serializable; import java.math.BigDecim ...

随机推荐

  1. 一个flag

    最近要学的东西 1.矩阵树定理 2.KM 3.FFT 4.单纯型 5.自动机系列 6.插头DP 7.计算几何(?) 8.数学相关(?)

  2. R语言绘图002-页面布局

    par().layout().split.screen()函数 1. par()函数的参数详解 函数par()可以用来设置或者获取图形参数,par()本身(括号中不写任何参数)返回当前的图形参数设置( ...

  3. Node.js 项目搭建

    关于 本书致力于教会你如何用Node.js来开发应用,过程中会传授你所有所需的“高级”JavaScript知识.本书绝不是一本“Hello World”的教程. 状态 你正在阅读的已经是本书的最终版. ...

  4. 如何实现SAP的RFC函数调用(原创)

    连接sap系统需要通过sap javaconnect来连接,对于sapjco.jar系列文件有32位与64位之分[32位用的JAR版本是 2.1.10 (2011-05-10) ,64位用的JAR版本 ...

  5. 23、获取app所占据的内存

    public static void getRunningAppProcessInfo(ActivityManager mActivityManager) { //ActivityManager mA ...

  6. 17、android设备如何防止屏幕休眠(转载)

    当你需要你的设备需要长期运行时,由于移动设备为了延长电池续航时间,在运行15s-30mins后(用户可自由设置),如果用户在此时间段内没有操作,系统将进入休眠状态并 将屏幕锁上,所以在需要长期运行时, ...

  7. Ionic 安装部署

    Ionic 安装部署 准备工作 下载安装Node.js, JDK,Apache Ant,Android SDK:编辑器用WebStorm node jdk ant 均需要加进 环境变量path中 An ...

  8. 【BZOJ】【3172】【TJOI2013】单词

    AC自动机 Orz zyf 玛雅一开始连题意都没看懂……意思就是给你一篇文章的N个单词,问每个单词在这篇文章中各出现了几次?(这篇文章=N个单词) 那么我们建个AC自动机……对于每个单词来说,它出现的 ...

  9. frequentism-and-bayesianism-chs-iv

    frequentism-and-bayesianism-chs-iv 频率主义与贝叶斯主义 IV:Python的贝叶斯工具   这个notebook出自Pythonic Perambulations的 ...

  10. VSS

    A deleted file of the same name already exists in this VSS project. Do you want to recover the delet ...