一、结构

二、配置文件约定

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. 使用JavaScript+Html创建win8应用(一)

            最近在学习win8 metro app的开发,今天刚刚学了一个小的例子,分享一下 开始之前你需要准备... 1.开发win8应用需要具备Windows 8 和 Microsoft Vi ...

  2. Shell遍历文件的每一行[转载]

    #!/bin/sh while read line do echo $line done < /home/jms/lab/input.txt

  3. 【WildCard Matching】cpp

    题目: Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any single charact ...

  4. gvim编辑文件到github乱码

    with below _vimrc settings, code uploaded to GitHub will display with proper encoding set encoding=u ...

  5. Android入门视频推荐

      marschen老师的Android入门视频推荐网址: 1.Android应用程序开发视频教程(重制版)第一季 2.Android应用开发视频教程(重制版)第二季 2.marschen老师的个人微 ...

  6. bzoj 3293 数学整理

    和1045一模一样,找到这道题的时候还愣了下神,最后发现样例都是 一样的,直接粘了1045的代码,具体题解看 http://www.cnblogs.com/BLADEVIL/p/3468729.htm ...

  7. hdu 3123 GCC 阶乘

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3123 The GNU Compiler Collection (usually shortened t ...

  8. sqlite时间比较语法

    如下: 字段 > datetime('2000-01-01 01:01:01') AND 字段 < datetime('2001-01-01 01:01:01');

  9. 使用开关、分段控件和web视图

    #import "XViewController.h" @interface XViewController () @end @implementation XViewContro ...

  10. linux下解压命令大全(转载)

    .tar 解包:tar xvf FileName.tar 打包:tar cvf FileName.tar DirName (注:tar是打包,不是压缩!) ——————————————— .gz 解压 ...