一、结构

二、配置文件约定

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. 什么是锚点(AnchorPoint)

    1.锚点通常是图形的几何中心, AnchorPoint(x,y)的两个参量x和y的取值通常都是0到1之间的实数,表示锚点相对于节点长宽的位置. 例如,把节点左下角作为锚点,值为(0,0): 把节点的中 ...

  2. ubuntu 13.04 163源(亲测可用)

    # deb cdrom:[Ubuntu )]/ trusty main restricted # See http://help.ubuntu.com/community/UpgradeNotes f ...

  3. linux查看端口是否已开启和查看文件数

    查看端口是否开启 lsof -i:80 查看文件数 ls | wc -w

  4. 新 四则运算题目 C++

    源代码: #include <stdlib.h>#include <iostream.h>#include <conio.h>#include <time.h ...

  5. xml基础学习笔记05

    Xpath快速解析 如题一样,本篇主要说说Xpath快速查找XML文档   * Xpatn.Xquery,是专门用来查询xml的语言   * 查询xml非常快   Xpatn.Xquery,是专门用来 ...

  6. 【Merge K Sorted Lists】cpp

    题目: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexit ...

  7. Netsharp FAQ

    1.启动服务器时候不能监听端口,出现如下错误: 回答: 这种问题应该是在win7环境下才有,是没有权限,要以管理员身份运行Netsharp.Elephant.Q.exe. 2.启动服务器的时候,服务端 ...

  8. 利用 js 实现弹出蒙板(model)功能

    关于 js 实现一个简单的蒙板功能(model) 思路: 创建一个蒙板, 设置蒙板的堆叠顺序保证能将其它元素盖住 position: absolute; top: 0; left: 0; displa ...

  9. maven插件:tomcat插件和jetty插件的区别

    在程序是多模块结构的时候,使用tomcat的maven插件和jetty的maven插件有细微差别: 1.tomcat7-maven-plugin   可以直接在parent的邮件直接运行:tomcat ...

  10. 【CentOS】搭建Web服务器

    参考资料:     http://www.paipat.com/?post=24     http://www.cnblogs.com/xiaoluo501395377/archive/2013/04 ...