一、结构

二、配置文件约定

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. 如何在Quartus II中设置Virtual pin

    为了验证FPGA工程中的某个模块的功能和时序的正确性,常常需要对其单独进行验证,但是这些模块通常都与内部的众多信号相连(如系统总线,中断信号线等),往往一个模块的对外接口引脚会多达几百个,对其单独仿真 ...

  2. 如何在github上fork一个项目来贡献代码以及同步原作者的修改

    [-] 如何贡献自己的力量 如何让自己的项目与原作者的项目保持同步 作为一个IT人,通过github进行学习是最快的成长手 段.我们可以浏览别人的优秀代码.但只看不动手还是成长得很慢,因此为别人贡献代 ...

  3. [磁盘管理与分区]——关于分区、磁盘分区表、MBR

    磁盘连接与设备文件名的关系 1. 如下图所示:

  4. JSP动作学习一

    创建一个简单的模拟登陆功能的网页,没有用数据库技术,只是简单的学习jsp语法 首先创建一个登陆页面 <%@ page language = "java" import=&qu ...

  5. 20145105 《Java程序设计》第2周学习总结

    20145105 <Java程序设计>第2周学习总结 教材学习内容总结 第三章主要的学习内容与c语言有很多相似的地方,讲述了Java的基本语法.其中涵盖: 1. 类型: - short整数 ...

  6. extjs4 与 kindeditor

    <link rel="stylesheet" href="<?php echo Yii::app()->request->baseUrl;?> ...

  7. 如何开始你的CTF比赛之旅-网站安全-

    在过去的两个星期里,我已经在DEFCON 22 CTF里检测出了两个不同的问题:“shitsco ”和“ nonameyet ”.感谢所有 的意见和评论,我遇到的最常见的问题是:“我怎么才能在CTFs ...

  8. Request/Server的相关topic

    Request---------Server模式 HTTP 协议--------->这个可能返回json, 也可能是HTML HTML页面处理的流程以及资源文件的加载 浏览器最大连接数 js资源 ...

  9. YARN应用程序的开发步骤

    开发基于YARN的应用程序需要开发客户端程序和AppMaster程序: 我们基于程序自带的例子来实现提交application 到YARN的ResourceManger. Distributed Sh ...

  10. self._raiseerror(v) File "D:\GameDevelopment\Python27\lib\xml\etree\ElementTree.py", line 1506, in _raiseerror

    D:\BaiDuYun\Plist>python unpack_plist.py lobbyRelieveTraceback (most recent call last): File &quo ...