JavaPersistenceWithHibernate第二版笔记-第四章-Mapping persistent classes-003映射实体时的可选操作(<delimited-identifiers/>、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\"")

若全部SQL都加定界符, create an orm.xml file and add the setting <delimited-identifiers/> to its <persistence-unit-defaults> section,Hibernate then enforces quoted identifiers everywhere.

3.若要映射的表都有前缀,则可用实现PhysicalNamingStrategy接口或继承已有的实现

 1 package org.jpwh.shared;
 2
 3 import org.hibernate.boot.model.naming.Identifier;
 4 import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
 5
 6 /**
 7  * Prefixes all SQL table names with "CE_", for CaveatEmptor.
 8  */
 9 public class CENamingStrategy extends
10     org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl {
11
12     @Override
13     public Identifier toPhysicalTableName(Identifier name,
14                                           JdbcEnvironment context) {
15         return new Identifier("CE_" + name.getText(), name.isQuoted());
16     }
17
18 }

You have to enable the naming-strategy implementation in persistence.xml:

1 <persistence-unit>name="CaveatEmptorPU">
2     ...
3     <properties>
4         <property name="hibernate.physical_naming_strategy" value="org.jpwh.shared.CENamingStrategy" />
5     </properties>
6 </persistence-unit>

4.用ImplicitNamingStrategy

二、自定义实体名

1.

1 package my.other.model;
2 @javax.persistence.Entity(name = "AuctionItem")
3 public class Item {
4     // ...
5 }

三、动态生成SQL

To disable generation of INSERT and UPDATE SQL statements on startup, you need native Hibernate annotations:

1 @Entity
2 @org.hibernate.annotations.DynamicInsert
3 @org.hibernate.annotations.DynamicUpdate
4 public class Item {
5     // ...
6 }

四、实体相关选项

1.Making an entity immutable

1 @Entity
2 @org.hibernate.annotations.Immutable
3 public class Bid {
4     // ...
5 }

2.Mapping an entity to a subselect

 1 package org.jpwh.model.advanced;
 2
 3 import javax.persistence.Entity;
 4 import javax.persistence.Id;
 5
 6 @Entity
 7 @org.hibernate.annotations.Immutable
 8 @org.hibernate.annotations.Subselect(
 9     value = "select i.ID as ITEMID, i.ITEM_NAME as NAME, " +
10             "count(b.ID) as NUMBEROFBIDS " +
11             "from ITEM i left outer join BID b on i.ID = b.ITEM_ID " +
12             "group by i.ID, i.ITEM_NAME"
13 )
14
15 // TODO Table names are case sensitive, Hibernate bug HHH-8430
16 @org.hibernate.annotations.Synchronize({"Item", "Bid"})
17 public class ItemBidSummary {
18
19     @Id
20     protected Long itemId;
21
22     protected String name;
23
24     protected long numberOfBids;
25
26     public ItemBidSummary() {
27     }
28
29     // Getter methods...
30     public Long getItemId() {
31         return itemId;
32     }
33
34     public String getName() {
35         return name;
36     }
37
38     public long getNumberOfBids() {
39         return numberOfBids;
40     }
41
42     // ...
43 }

五、测试代码

1.

 1 package org.jpwh.test.advanced;
 2
 3 import org.jpwh.env.JPATest;
 4 import org.jpwh.model.advanced.Bid;
 5 import org.jpwh.model.advanced.Item;
 6 import org.jpwh.model.advanced.ItemBidSummary;
 7 import org.testng.annotations.Test;
 8
 9 import javax.persistence.EntityManager;
10 import javax.persistence.Query;
11 import javax.transaction.UserTransaction;
12 import java.math.BigDecimal;
13
14 import static org.testng.Assert.assertEquals;
15
16 public class MappedSubselect extends JPATest {
17
18     @Override
19     public void configurePersistenceUnit() throws Exception {
20         configurePersistenceUnit("AdvancedPU");
21     }
22
23     @Test
24     public void loadSubselectEntity() throws Exception {
25         long ITEM_ID = storeItemAndBids();
26
27         UserTransaction tx = TM.getUserTransaction();
28         try {
29             tx.begin();
30             EntityManager em = JPA.createEntityManager();
31
32             {
33                 ItemBidSummary itemBidSummary = em.find(ItemBidSummary.class, ITEM_ID);
34                 // select * from (
35                 //      select i.ID as ITEMID, i.ITEM_NAME as NAME, ...
36                 // ) where ITEMID = ?
37
38                 assertEquals(itemBidSummary.getName(), "AUCTION: Some item");
39             }
40             em.clear();
41
42             { // Hibernate will synchronize the right tables before querying
43                 Item item = em.find(Item.class, ITEM_ID);
44                 item.setName("New name");
45
46                 // No flush before retrieval by identifier!
47                  //ItemBidSummary itemBidSummary = em.find(ItemBidSummary.class, ITEM_ID);
48
49                 // Automatic flush before queries if synchronized tables are affected!
50                 Query query = em.createQuery(
51                     "select ibs from ItemBidSummary ibs where ibs.itemId = :id"
52                 );
53                 ItemBidSummary itemBidSummary =
54                     (ItemBidSummary)query.setParameter("id", ITEM_ID).getSingleResult();
55
56                 assertEquals(itemBidSummary.getName(), "AUCTION: New name");
57             }
58
59             tx.commit();
60             em.close();
61         } finally {
62             TM.rollback();
63         }
64     }
65
66     public Long storeItemAndBids() throws Exception {
67         UserTransaction tx = TM.getUserTransaction();
68         tx.begin();
69         EntityManager em = JPA.createEntityManager();
70         Item item = new Item();
71         item.setName("Some item");
72         item.setDescription("This is some description.");
73         em.persist(item);
74         for (int i = 1; i <= 3; i++) {
75             Bid bid = new Bid();
76             bid.setAmount(new BigDecimal(10 + i));
77             bid.setItem(item);
78             em.persist(bid);
79         }
80         tx.commit();
81         em.close();
82         return item.getId();
83     }
84
85 }

Note that Hibernate doesn’t flush automatically before a find() operation—only before a Query is executed, if necessary. Hibernate detects that the modified Item will affect the result of the query, because the ITEM table is synchronized with ItemBid-Summary . Hence, a flush and the UPDATE of the ITEM row are necessary to avoid the

query returning stale data.

2.

  1 package org.jpwh.model.advanced;
  2
  3 import org.jpwh.model.Constants;
  4
  5 import javax.persistence.Access;
  6 import javax.persistence.AccessType;
  7 import javax.persistence.Basic;
  8 import javax.persistence.Column;
  9 import javax.persistence.Entity;
 10 import javax.persistence.EnumType;
 11 import javax.persistence.Enumerated;
 12 import javax.persistence.FetchType;
 13 import javax.persistence.GeneratedValue;
 14 import javax.persistence.Id;
 15 import javax.persistence.Lob;
 16 import javax.persistence.Temporal;
 17 import javax.persistence.TemporalType;
 18 import javax.validation.constraints.NotNull;
 19 import java.math.BigDecimal;
 20 import java.sql.Blob;
 21 import java.util.Date;
 22
 23 @Entity
 24 public class Item {
 25
 26     /*
 27        The <code>Item</code> entity defaults to field access, the <code>@Id</code> is on a field. (We
 28        have also moved the brittle <code>ID_GENERATOR</code> string into a constant.)
 29      */
 30     @Id
 31     @GeneratedValue(generator = Constants.ID_GENERATOR)
 32     protected Long id;
 33
 34     @org.hibernate.annotations.Type(type = "yes_no")
 35     protected boolean verified = false;
 36
 37     // JPA says @Temporal is required but Hibernate will default to TIMESTAMP without it
 38     @Temporal(TemporalType.TIMESTAMP)
 39     @Column(updatable = false)
 40     @org.hibernate.annotations.CreationTimestamp
 41     protected Date createdOn;
 42
 43     // Java 8 API
 44     // protected Instant reviewedOn;
 45
 46     @NotNull
 47     @Basic(fetch = FetchType.LAZY) // Defaults to EAGER
 48     protected String description;
 49
 50     @Basic(fetch = FetchType.LAZY)
 51     @Column(length = 131072) // 128 kilobyte maximum for the picture
 52     protected byte[] image; // Maps to SQL VARBINARY type
 53
 54     @Lob
 55     protected Blob imageBlob;
 56
 57     @NotNull
 58     @Enumerated(EnumType.STRING) // Defaults to ORDINAL
 59     protected AuctionType auctionType = AuctionType.HIGHEST_BID;
 60
 61     @org.hibernate.annotations.Formula(
 62         "substr(DESCRIPTION, 1, 12) || ‘...‘"
 63     )
 64     protected String shortDescription;
 65
 66     @org.hibernate.annotations.Formula(
 67         "(select avg(b.AMOUNT) from BID b where b.ITEM_ID = ID)"
 68     )
 69     protected BigDecimal averageBidAmount;
 70
 71     @Column(name = "IMPERIALWEIGHT")
 72     @org.hibernate.annotations.ColumnTransformer(
 73         read = "IMPERIALWEIGHT / 2.20462",
 74         write = "? * 2.20462"
 75     )
 76     protected double metricWeight;
 77
 78     @Temporal(TemporalType.TIMESTAMP)
 79     @Column(insertable = false, updatable = false)
 80     @org.hibernate.annotations.Generated(
 81         org.hibernate.annotations.GenerationTime.ALWAYS
 82     )
 83     protected Date lastModified;
 84
 85     @Column(insertable = false)
 86     @org.hibernate.annotations.ColumnDefault("1.00")
 87     @org.hibernate.annotations.Generated(
 88         org.hibernate.annotations.GenerationTime.INSERT
 89     )
 90     protected BigDecimal initialPrice;
 91
 92     /*
 93         The <code>@Access(AccessType.PROPERTY)</code> setting on the <code>name</code> field switches this
 94         particular property to runtime access through getter/setter methods by the JPA provider.
 95      */
 96     @Access(AccessType.PROPERTY)
 97     @Column(name = "ITEM_NAME") // Mappings are still expected here!
 98     protected String name;
 99
100     /*
101         Hibernate will call <code>getName()</code> and <code>setName()</code> when loading and storing items.
102      */
103     public String getName() {
104         return name;
105     }
106
107     public void setName(String name) {
108         this.name =
109             !name.startsWith("AUCTION: ") ? "AUCTION: " + name : name;
110     }
111
112     public Long getId() { // Optional but useful
113         return id;
114     }
115
116     public String getDescription() {
117         return description;
118     }
119
120     public void setDescription(String description) {
121         this.description = description;
122     }
123
124     public String getShortDescription() {
125         return shortDescription;
126     }
127
128     public BigDecimal getAverageBidAmount() {
129         return averageBidAmount;
130     }
131
132     public double getMetricWeight() {
133         return metricWeight;
134     }
135
136     public void setMetricWeight(double metricWeight) {
137         this.metricWeight = metricWeight;
138     }
139
140     public Date getLastModified() {
141         return lastModified;
142     }
143
144     public BigDecimal getInitialPrice() {
145         return initialPrice;
146     }
147
148     public Date getCreatedOn() {
149         return createdOn;
150     }
151
152     public boolean isVerified() {
153         return verified;
154     }
155
156     public void setVerified(boolean verified) {
157         this.verified = verified;
158     }
159
160     public byte[] getImage() {
161         return image;
162     }
163
164     public void setImage(byte[] image) {
165         this.image = image;
166     }
167
168     public Blob getImageBlob() {
169         return imageBlob;
170     }
171
172     public void setImageBlob(Blob imageBlob) {
173         this.imageBlob = imageBlob;
174     }
175
176     public AuctionType getAuctionType() {
177         return auctionType;
178     }
179
180     public void setAuctionType(AuctionType auctionType) {
181         this.auctionType = auctionType;
182     }
183 }

3.

 1 package org.jpwh.model.advanced;
 2
 3 import org.jpwh.model.Constants;
 4
 5 import javax.persistence.Entity;
 6 import javax.persistence.FetchType;
 7 import javax.persistence.GeneratedValue;
 8 import javax.persistence.Id;
 9 import javax.persistence.JoinColumn;
10 import javax.persistence.ManyToOne;
11 import javax.validation.constraints.NotNull;
12 import java.math.BigDecimal;
13
14 @Entity
15 @org.hibernate.annotations.Immutable
16 public class Bid {
17
18     @Id
19     @GeneratedValue(generator = Constants.ID_GENERATOR)
20     protected Long id;
21
22     @NotNull
23     protected BigDecimal amount;
24
25     @ManyToOne(optional = false, fetch = FetchType.LAZY) // NOT NULL
26     @JoinColumn(name = "ITEM_ID") // Actually the default name
27     protected Item item;
28
29     public Long getId() {
30         return id;
31     }
32
33     public BigDecimal getAmount() {
34         return amount;
35     }
36
37     public void setAmount(BigDecimal amount) {
38         this.amount = amount;
39     }
40
41     public Item getItem() {
42         return item;
43     }
44
45     public void setItem(Item item) {
46         this.item = item;
47     }
48 }
时间: 2024-10-13 15:37:24

JavaPersistenceWithHibernate第二版笔记-第四章-Mapping persistent classes-003映射实体时的可选操作(<delimited-identifiers/>、PhysicalNamingStrategy、PhysicalNamingStrategyStandardImpl、、、)的相关文章

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 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 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第二版笔记-第五章-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

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

Python核心编程(第二版) 第四章习题答案

4-1.Python对象.与所有Python对象有关的三个属性是什么?请简单的描述一下.答:与所有Python对象有关的三个属性是身份.类型.值.身份:每一个对象都有一个唯一的身份标识自己,任何对象的身份可以使用内建函数id()来得到.这个值可以被认为是该对象的内存地址.类型:对象的类型决定了该对象可以保存什么类型的值,可以进行什么样的操作,以及遵循什么规则.可以用内建函数type()来查看Python的类型.值:对象表示的数据项.4-2.类型.不可更改(immutable)指的是什么?Pyth

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