JavaPersistenceWithHibernate第二版笔记Getting started with ORM-002Domain层详解及M etaModel

一、结构

二、配置文件约定

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

 1 <entity-mappings
 2         version="2.1"
 3         xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
 4         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm
 6             http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd">
 7
 8     <!-- First, global metadata -->
 9     <persistence-unit-metadata>
10
11         <!-- Ignore all annotations, all mapping metadata in XML files -->
12         <xml-mapping-metadata-complete/>
13
14         <!-- Some default settings -->
15         <persistence-unit-defaults>
16             <!--
17                 Escape all SQL column/table/etc. names, e.g. if your SQL
18                 names are actually keywords (a "USER" table for example)
19               -->
20             <delimited-identifiers/>
21         </persistence-unit-defaults>
22
23     </persistence-unit-metadata>
24
25     <entity class="org.jpwh.model.simple.Item" access="FIELD">
26         <attributes>
27             <id name="id">
28                 <generated-value strategy="AUTO"/>
29             </id>
30             <basic name="name"/>
31             <basic name="auctionEnd">
32                 <temporal>TIMESTAMP</temporal>
33             </basic>
34             <transient name="bids"/>
35             <transient name="category"/>
36         </attributes>
37     </entity>
38
39 </entity-mappings>

2.MappingsOverride.xml

 1 <entity-mappings
 2         version="2.1"
 3         xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
 4         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm
 6             http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd">
 7
 8     <entity class="org.jpwh.model.simple.Item">
 9         <attributes>
10             <!-- Override the SQL column name -->
11             <basic name="name">
12                 <column name="ITEM_NAME"/>
13             </basic>
14         </attributes>
15     </entity>
16
17 </entity-mappings>

3.Queries.xml

 1 <entity-mappings
 2         version="2.1"
 3         xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
 4         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm
 6             http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd">
 7
 8     <named-query name="findItems">
 9         <query><![CDATA[
10         select i from Item i
11         ]]></query>
12     </named-query>
13
14     <named-query name="findItemsWithHints">
15         <query>select i from Item i</query>
16         <hint name="org.hibernate.comment" value="My Comment"/>
17         <hint name="org.hibernate.fetchSize" value="50"/>
18         <hint name="org.hibernate.readOnly" value="true"/>
19         <hint name="org.hibernate.timeout" value="60"/>
20     </named-query>
21
22 </entity-mappings>

4.Native.hbm.xml

 1 <?xml version="1.0"?>
 2 <!--
 3   Metadata is declared inside a <code>&lt;hibernate-mapping&gt;</code> root element. Attributes such as
 4   <code>package</code> name and <code>default-access</code> apply to all mappings in this file. You may include as many
 5   entity class mappings as you like.
 6   -->
 7 <hibernate-mapping
 8         xmlns="http://www.hibernate.org/xsd/orm/hbm"
 9         package="org.jpwh.model.simple"
10         default-access="field">
11
12     <!-- An entity class mapping -->
13     <class name="Item">
14         <id name="id">
15             <generator class="native"/>
16         </id>
17         <property name="name"/>
18         <property name="auctionEnd" type="timestamp"/>
19     </class>
20
21     <!-- Externalized queries -->
22     <query name="findItemsHibernate">select i from Item i</query>
23
24     <!-- Auxiliary schema DDL -->
25     <database-object>
26         <create>create index ITEM_NAME_IDX on ITEM(NAME)</create>
27         <drop>drop index if exists ITEM_NAME_IDX</drop>
28     </database-object>
29
30 </hibernate-mapping>

三、domain层

1.

 1 package org.jpwh.model.querying;
 2
 3 import org.jpwh.model.Constants;
 4
 5 import javax.persistence.*;
 6 import javax.validation.constraints.NotNull;
 7 import java.math.BigDecimal;
 8
 9 @Entity
10 public class Bid {
11
12     @Id
13     @GeneratedValue(generator = Constants.ID_GENERATOR)
14     protected Long id;
15
16     @NotNull
17     @ManyToOne(fetch = FetchType.LAZY)
18     @JoinColumn(foreignKey = @ForeignKey(name = "FK_BID_ITEM_ID"))
19     protected Item item;
20
21     @ManyToOne(optional = false, fetch = FetchType.LAZY)
22     @JoinColumn(foreignKey = @ForeignKey(name = "FK_BID_BIDDER_ID"))
23     protected User bidder;
24
25     @NotNull
26     protected BigDecimal amount;
27
28     public Bid() {
29     }
30
31     public Bid(Item item, User bidder, BigDecimal amount) {
32         this.item = item;
33         this.amount = amount;
34         this.bidder = bidder;
35     }
36
37     public Item getItem() {
38         return item;
39     }
40
41     public void setItem(Item item) {
42         this.item = item;
43     }
44
45     public User getBidder() {
46         return bidder;
47     }
48
49     public void setBidder(User bidder) {
50         this.bidder = bidder;
51     }
52
53     public BigDecimal getAmount() {
54         return amount;
55     }
56
57     public void setAmount(BigDecimal amount) {
58         this.amount = amount;
59     }
60 }

2.

  1 package org.jpwh.model.querying;
  2
  3 import org.jpwh.model.Constants;
  4
  5 import javax.persistence.*;
  6 import javax.validation.constraints.NotNull;
  7 import java.math.BigDecimal;
  8 import java.util.Date;
  9 import java.util.HashSet;
 10 import java.util.Set;
 11
 12 @NamedQueries({
 13     @NamedQuery(
 14         name = "findItemById",
 15         query = "select i from Item i where i.id = :id"
 16     )
 17     ,
 18     @NamedQuery(
 19         name = "findItemByName",
 20         query = "select i from Item i where i.name like :name",
 21         hints = {
 22             @QueryHint(
 23                 name = org.hibernate.annotations.QueryHints.TIMEOUT_JPA,
 24                 value = "60000"),
 25             @QueryHint(
 26                 name = org.hibernate.annotations.QueryHints.COMMENT,
 27                 value = "Custom SQL comment")
 28         }
 29     )
 30 })
 31 @SqlResultSetMappings({
 32     @SqlResultSetMapping(
 33         name = "ItemResult",
 34         entities =
 35         @EntityResult(
 36             entityClass = Item.class,
 37             fields = {
 38                 @FieldResult(name = "id", column = "ID"),
 39                 @FieldResult(name = "name", column = "EXTENDED_NAME"),
 40                 @FieldResult(name = "createdOn", column = "CREATEDON"),
 41                 @FieldResult(name = "auctionEnd", column = "AUCTIONEND"),
 42                 @FieldResult(name = "auctionType", column = "AUCTIONTYPE"),
 43                 @FieldResult(name = "approved", column = "APPROVED"),
 44                 @FieldResult(name = "buyNowPrice", column = "BUYNOWPRICE"),
 45                 @FieldResult(name = "seller", column = "SELLER_ID")
 46             }
 47         )
 48     )
 49 })
 50 @Entity
 51 public class Item {
 52
 53     @Id
 54     @GeneratedValue(generator = Constants.ID_GENERATOR)
 55     protected Long id;
 56
 57     @NotNull
 58     protected String name;
 59
 60     @NotNull
 61     protected Date createdOn = new Date();
 62
 63     @NotNull
 64     protected Date auctionEnd;
 65
 66     @NotNull
 67     @Enumerated(EnumType.STRING)
 68     protected AuctionType auctionType = AuctionType.HIGHEST_BID;
 69
 70     @NotNull
 71     protected boolean approved = true;
 72
 73     protected BigDecimal buyNowPrice;
 74
 75     @ManyToOne(optional = false, fetch = FetchType.LAZY)
 76     @JoinColumn(foreignKey = @ForeignKey(name = "FK_ITEM_SELLER_ID"))
 77     protected User seller;
 78
 79     @ManyToMany(mappedBy = "items")
 80     protected Set<Category> categories = new HashSet<>();
 81
 82     @OneToMany(mappedBy = "item")
 83     protected Set<Bid> bids = new HashSet<>();
 84
 85     @ElementCollection
 86     @JoinColumn(foreignKey = @ForeignKey(name = "FK_ITEM_IMAGES_ITEM_ID"))
 87     protected Set<Image> images = new HashSet<>();
 88
 89     public Item() {
 90     }
 91
 92     public Item(String name, Date auctionEnd, User seller) {
 93         this.name = name;
 94         this.auctionEnd = auctionEnd;
 95         this.seller = seller;
 96     }
 97
 98     public Long getId() {
 99         return id;
100     }
101
102     public String getName() {
103         return name;
104     }
105
106     public void setName(String name) {
107         this.name = name;
108     }
109
110     public Date getCreatedOn() {
111         return createdOn;
112     }
113
114     public Date getAuctionEnd() {
115         return auctionEnd;
116     }
117
118     public void setAuctionEnd(Date auctionEnd) {
119         this.auctionEnd = auctionEnd;
120     }
121
122     public AuctionType getAuctionType() {
123         return auctionType;
124     }
125
126     public void setAuctionType(AuctionType auctionType) {
127         this.auctionType = auctionType;
128     }
129
130     public boolean isApproved() {
131         return approved;
132     }
133
134     public void setApproved(boolean approved) {
135         this.approved = approved;
136     }
137
138     public BigDecimal getBuyNowPrice() {
139         return buyNowPrice;
140     }
141
142     public void setBuyNowPrice(BigDecimal buyNowPrice) {
143         this.buyNowPrice = buyNowPrice;
144     }
145
146     public User getSeller() {
147         return seller;
148     }
149
150     public void setSeller(User seller) {
151         this.seller = seller;
152     }
153
154     public Set<Category> getCategories() {
155         return categories;
156     }
157
158     public void setCategories(Set<Category> categories) {
159         this.categories = categories;
160     }
161
162     public Set<Bid> getBids() {
163         return bids;
164     }
165
166     public void setBids(Set<Bid> bids) {
167         this.bids = bids;
168     }
169
170     public Set<Image> getImages() {
171         return images;
172     }
173
174     public void setImages(Set<Image> images) {
175         this.images = images;
176     }
177     // ...
178 }

3.

 1 @org.hibernate.annotations.NamedQueries({
 2     @org.hibernate.annotations.NamedQuery(
 3         name = "findItemsOrderByName",
 4         query = "select i from Item i order by i.name asc"
 5     )
 6     ,
 7     @org.hibernate.annotations.NamedQuery(
 8         name = "findItemBuyNowPriceGreaterThan",
 9         query = "select i from Item i where i.buyNowPrice > :price",
10         timeout = 60, // Seconds!
11         comment = "Custom SQL comment"
12     )
13 })
14
15 package org.jpwh.model.querying;

四、测试文件

1.

 1 package org.jpwh.test.simple;
 2
 3 import org.jpwh.model.simple.Bid;
 4 import org.jpwh.model.simple.Item;
 5 import org.testng.annotations.Test;
 6
 7 import javax.validation.ConstraintViolation;
 8 import javax.validation.Validation;
 9 import javax.validation.Validator;
10 import javax.validation.ValidatorFactory;
11 import java.util.Date;
12 import java.util.Locale;
13 import java.util.Set;
14
15 import static org.testng.Assert.*;
16
17 public class ModelOperations {
18
19     @Test
20     public void linkBidAndItem() {
21         Item anItem = new Item();
22         Bid aBid = new Bid();
23
24         anItem.getBids().add(aBid);
25         aBid.setItem(anItem);
26
27         assertEquals(anItem.getBids().size(), 1);
28         assertTrue(anItem.getBids().contains(aBid));
29         assertEquals(aBid.getItem(), anItem);
30
31         // Again with convenience method
32         Bid secondBid = new Bid();
33         anItem.addBid(secondBid);
34
35         assertEquals(2, anItem.getBids().size());
36         assertTrue(anItem.getBids().contains(secondBid));
37         assertEquals(anItem, secondBid.getItem());
38     }
39
40     @Test
41     public void validateItem() {
42         ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
43         Validator validator = factory.getValidator();
44
45         Item item = new Item();
46         item.setName("Some Item");
47         item.setAuctionEnd(new Date());
48
49         Set<ConstraintViolation<Item>> violations = validator.validate(item);
50
51         // We have one validation error, auction end date was not in the future!
52         assertEquals(1, violations.size());
53
54         ConstraintViolation<Item> violation = violations.iterator().next();
55         String failedPropertyName =
56                 violation.getPropertyPath().iterator().next().getName();
57
58         assertEquals(failedPropertyName, "auctionEnd");
59
60         if (Locale.getDefault().getLanguage().equals("en"))
61             assertEquals(violation.getMessage(), "must be in the future");
62     }
63
64 }

2.

  1 package org.jpwh.test.simple;
  2
  3 import org.jpwh.env.JPATest;
  4 import org.jpwh.model.simple.Item;
  5 //import org.jpwh.model.simple.Item_;
  6 import org.testng.annotations.Test;
  7
  8 import javax.persistence.EntityManager;
  9 import javax.persistence.EntityManagerFactory;
 10 import javax.persistence.criteria.CriteriaBuilder;
 11 import javax.persistence.criteria.CriteriaQuery;
 12 import javax.persistence.criteria.Path;
 13 import javax.persistence.criteria.Root;
 14 import javax.persistence.metamodel.Attribute;
 15 import javax.persistence.metamodel.ManagedType;
 16 import javax.persistence.metamodel.Metamodel;
 17 import javax.persistence.metamodel.SingularAttribute;
 18 import javax.persistence.metamodel.Type;
 19 import javax.transaction.UserTransaction;
 20 import java.util.Date;
 21 import java.util.List;
 22 import java.util.Set;
 23
 24 import static org.testng.Assert.assertEquals;
 25 import static org.testng.Assert.assertFalse;
 26
 27 public class AccessJPAMetamodel extends JPATest {
 28
 29     @Override
 30     public void configurePersistenceUnit() throws Exception {
 31         configurePersistenceUnit("SimpleXMLCompletePU");
 32     }
 33
 34     @Test
 35     public void accessDynamicMetamodel() throws Exception {
 36         EntityManagerFactory entityManagerFactory = JPA.getEntityManagerFactory();
 37
 38         Metamodel mm = entityManagerFactory.getMetamodel();
 39
 40         Set<ManagedType<?>> managedTypes = mm.getManagedTypes();
 41         assertEquals(managedTypes.size(), 1);
 42
 43         ManagedType itemType = managedTypes.iterator().next();
 44         assertEquals(
 45             itemType.getPersistenceType(),
 46             Type.PersistenceType.ENTITY
 47         );
 48
 49         SingularAttribute nameAttribute =
 50             itemType.getSingularAttribute("name");
 51         assertEquals(
 52             nameAttribute.getJavaType(),
 53             String.class
 54         );
 55         assertEquals(
 56             nameAttribute.getPersistentAttributeType(),
 57             Attribute.PersistentAttributeType.BASIC
 58         );
 59         assertFalse(
 60             nameAttribute.isOptional() // NOT NULL
 61         );
 62
 63         SingularAttribute auctionEndAttribute =
 64             itemType.getSingularAttribute("auctionEnd");
 65         assertEquals(
 66             auctionEndAttribute.getJavaType(),
 67             Date.class
 68         );
 69         assertFalse(
 70             auctionEndAttribute.isCollection()
 71         );
 72         assertFalse(
 73             auctionEndAttribute.isAssociation()
 74         );
 75     }
 76
 77 /*    @Test
 78     public void accessStaticMetamodel() throws Exception {
 79
 80         SingularAttribute nameAttribute = Item_.name;
 81
 82         assertEquals(
 83             nameAttribute.getJavaType(),
 84             String.class
 85         );
 86     }*/
 87
 88     @Test
 89     public void queryStaticMetamodel() throws Exception {
 90         UserTransaction tx = TM.getUserTransaction();
 91         try {
 92             tx.begin();
 93
 94             EntityManager entityManager = JPA.createEntityManager();
 95
 96             Item itemOne = new Item();
 97             itemOne.setName("This is some item");
 98             itemOne.setAuctionEnd(new Date(System.currentTimeMillis() + 100000));
 99             entityManager.persist(itemOne);
100
101             Item itemTwo = new Item();
102             itemTwo.setName("Another item");
103             itemTwo.setAuctionEnd(new Date(System.currentTimeMillis() + 100000));
104
105             entityManager.persist(itemTwo);
106
107             tx.commit();
108             entityManager.close();
109
110             entityManager = JPA.createEntityManager();
111             tx.begin();
112
113             CriteriaBuilder cb = entityManager.getCriteriaBuilder();
114
115             // This query is the equivalent of "select i from Item i"
116             CriteriaQuery<Item> query = cb.createQuery(Item.class);
117             Root<Item> fromItem = query.from(Item.class);
118             query.select(fromItem);
119
120             List<Item> items =
121                 entityManager.createQuery(query)
122                     .getResultList();
123
124             assertEquals(items.size(), 2);
125
126             // "where i.name like :pattern"
127             Path<String> namePath = fromItem.get("name");
128             query.where(
129                 cb.like(
130                     namePath, // Has to be a Path<String> for like() operator!
131                     cb.parameter(String.class, "pattern")
132                 )
133             );
134
135             items =
136                 entityManager.createQuery(query)
137                     .setParameter("pattern", "%some item%") // Wildcards!
138                     .getResultList();
139
140             assertEquals(items.size(), 1);
141             assertEquals(items.iterator().next().getName(), "This is some item");
142
143 //            query.where(
144 //                cb.like(
145 //                    fromItem.get(Item_.name), // Static Item_ metamodel!
146 //                    cb.parameter(String.class, "pattern")
147 //                )
148 //            );
149
150             items =
151                 entityManager.createQuery(query)
152                     .setParameter("pattern", "%some item%") // Wildcard!
153                     .getResultList();
154
155             assertEquals(items.size(), 1);
156             assertEquals(items.iterator().next().getName(), "This is some item");
157
158             tx.commit();
159             entityManager.close();
160         } finally {
161             TM.rollback();
162         }
163     }
164
165 }
时间: 2024-08-08 13:56:27

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

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

一.简介 1.You now have three methods for distinguishing references: ? Objects are identical if they occupy the same memory location in the JVM . This can be checked with the a == b operator. This concept is known as object identity.? Objects are equal i

JavaPersistenceWithHibernate第二版笔记-第四章-Mapping persistent classes-003映射实体时的可选操作(&lt;delimited-identifiers/&gt;、PhysicalNamingStrategy、PhysicalNamingStrategyStandardImpl、、、)

一.自定义映射的表名 1. 1 @Entity 2 @Table(name = "USERS") 3 public class User implements Serializable { 4 // ... 5 } 2.用定界符 1 //@Table(name = "`USER`")的标准 2 @Table(name = "`USER`") 3 4 //JPA的标准 5 @Table(name = "\"USER\"

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

一.结构 二.model层 1. 1 package org.jpwh.model.helloworld; 2 3 import javax.persistence.Entity; 4 import javax.persistence.GeneratedValue; 5 import javax.persistence.GenerationType; 6 import javax.persistence.Id; 7 8 /* 9 Every persistent entity class mus

JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-004Table per class hierarchy(@Inheritance..SINGLE_TABLE)、@DiscriminatorColumn、@DiscriminatorValue、@DiscriminatorFormula)

一.结构 You can map an entire class hierarchy to a single table. This table includes columns for all properties of all classes in the hierarchy. The value of an extra type discriminator column or formula identifies the concrete subclass represented by a

JavaPersistenceWithHibernate第二版笔记-第七章-004Mapping a map(@MapKeyEnumerated 、 @MapKeyTemporal、@MapKeyColumn)

一.结构 二.代码 1. 1 package org.jpwh.model.collections.mapofstrings; 2 3 import org.jpwh.model.Constants; 4 5 import javax.persistence.CollectionTable; 6 import javax.persistence.Column; 7 import javax.persistence.ElementCollection; 8 import javax.persist

JavaPersistenceWithHibernate第二版笔记-第七章-003Mapping an identifier bag(@OrderColumn、@ElementCollection、@CollectionTable、、)

一.结构 二.代码 1. 1 package org.jpwh.model.collections.listofstrings; 2 3 import org.jpwh.model.Constants; 4 5 import javax.persistence.CollectionTable; 6 import javax.persistence.Column; 7 import javax.persistence.ElementCollection; 8 import javax.persis

JavaPersistenceWithHibernate第二版笔记-第七章-001Mapping a set(@ElementCollection、@CollectionTable、@JoinColumn、)

一.结构 二.代码 1. 1 package org.jpwh.model.collections.setofstrings; 2 3 import org.jpwh.model.Constants; 4 5 import javax.persistence.CollectionTable; 6 import javax.persistence.Column; 7 import javax.persistence.ElementCollection; 8 import javax.persist

JavaPersistenceWithHibernate第二版笔记-第四章-Mapping persistent classes-001区分entities and value types

一.介绍 1.这种引用方式不对,但删除时不能级联 要这种引用方式 2.The Bid class could be a problem. In object-oriented modeling, this is marked as a composition (the association between Item and Bid with the diamond). Thus, an Item is the owner of its Bid instances and holds a col

JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-004嵌套组件的注解AttributeOverrides

一.数据库 二.代码 1. 1 package org.jpwh.model.advanced; 2 3 import javax.persistence.AttributeOverride; 4 import javax.persistence.AttributeOverrides; 5 import javax.persistence.Column; 6 import javax.persistence.Embeddable; 7 import javax.validation.constr