一、结构

二、配置文件约定

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. UIWebView swift

    // // ViewController.swift // UILabelTest // // Created by mac on 15/6/23. // Copyright (c) 2015年 fa ...

  2. matlab求距一个数最近的奇(偶)数

    int_a = floor(a);minEven = int_a+mod(int_a,2); %最近偶数minOdd = int_a+1-mod(int_a,2); %最近奇数

  3. 站立会议 ~NO.1

    Yesterday:None Today: Search for offline maps of our school and testify the veracities of it Problem ...

  4. Write operations are not allowed in read-only mode (FlushMode.NEVER/

    今天在做ssh项目开发的时候遇到一个问题,保存数据的时候报错: Write operations are not allowed in read-only mode (FlushMode.NEVER/ ...

  5. 深入浅出谈4G ─ 4G LTE网速到底有多快?

    常说4G网速能达100MHz,实际感受远远没有这么快.今天和大家一起算算帐,算算4G LTE网速到底有多快. 基本概念1:资源粒子 个资源粒子就是用个子载波传送个OFDM符号. 1个子载波的带宽是15 ...

  6. python 数据结构-元组tuple

    tuple0=() #空 tuple1="wo", #元组中包括单个元素用, tuple2="monkey","cat","chi ...

  7. 【CentOS】IBM X3650M4 IMM远程管理【转载】

    问题描述:          IBM X3650M4 IMM远程开机和关机   参考资料:             http://www.ibmsys.cn/blog/?p=201   问题解决: 一 ...

  8. boost之signal

    boost里的signal是一个模板类,不区分信号种类,产生信号统一用()调用操作符. 1.回调普通函数代码示例: #include <iostream> #include <str ...

  9. Codeforces Round #277.5 (Div. 2)

    题目链接:http://codeforces.com/contest/489 A:SwapSort In this problem your goal is to sort an array cons ...

  10. MAC下搭建web开发环境

    具体做法,参照此链接:http://mallinson.ca/osx-web-development/ Mac系统本身自带apache和PHP,MySQL可以安装也可以不安装 web开发的IDE可以是 ...