JavaPersistenceWithHibernate第二版笔记-第四章-Mapping persistent classes-003映射实体时的可选操作(<delimited-identifiers/>、PhysicalNamingStrategy、PhysicalNamingStrategyStandardImpl、、、)
一、自定义映射的表名
1.
@Entity
@Table(name = "USERS")
public class User implements Serializable {
// ...
}
2.用定界符
//@Table(name = "`USER`")的标准
@Table(name = "`USER`") //JPA的标准
@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接口或继承已有的实现
package org.jpwh.shared; import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; /**
* Prefixes all SQL table names with "CE_", for CaveatEmptor.
*/
public class CENamingStrategy extends
org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl { @Override
public Identifier toPhysicalTableName(Identifier name,
JdbcEnvironment context) {
return new Identifier("CE_" + name.getText(), name.isQuoted());
} }
You have to enable the naming-strategy implementation in persistence.xml:
<persistence-unit>name="CaveatEmptorPU">
...
<properties>
<property name="hibernate.physical_naming_strategy" value="org.jpwh.shared.CENamingStrategy" />
</properties>
</persistence-unit>
4.用ImplicitNamingStrategy
二、自定义实体名
1.
package my.other.model;
@javax.persistence.Entity(name = "AuctionItem")
public class Item {
// ...
}
三、动态生成SQL
To disable generation of INSERT and UPDATE SQL statements on startup, you need native Hibernate annotations:
@Entity
@org.hibernate.annotations.DynamicInsert
@org.hibernate.annotations.DynamicUpdate
public class Item {
// ...
}
四、实体相关选项
1.Making an entity immutable
@Entity
@org.hibernate.annotations.Immutable
public class Bid {
// ...
}
2.Mapping an entity to a subselect
When an instance of ItemBidSummary is loaded, Hibernate executes your custom SQL
SELECT as a subselect:
Synchronize注解的作用:Hibernate will then know it has to flush modifications of Item and Bid instances
before it executes a query against ItemBidSummary
package org.jpwh.model.advanced; import javax.persistence.Entity;
import javax.persistence.Id; @Entity
@org.hibernate.annotations.Immutable
@org.hibernate.annotations.Subselect(
value = "select i.ID as ITEMID, i.ITEM_NAME as NAME, " +
"count(b.ID) as NUMBEROFBIDS " +
"from ITEM i left outer join BID b on i.ID = b.ITEM_ID " +
"group by i.ID, i.ITEM_NAME"
) // TODO Table names are case sensitive, Hibernate bug HHH-8430
@org.hibernate.annotations.Synchronize({"Item", "Bid"})
public class ItemBidSummary { @Id
protected Long itemId; protected String name; protected long numberOfBids; public ItemBidSummary() {
} // Getter methods...
public Long getItemId() {
return itemId;
} public String getName() {
return name;
} public long getNumberOfBids() {
return numberOfBids;
} // ...
}
五、测试代码
1.
package org.jpwh.test.advanced; import org.jpwh.env.JPATest;
import org.jpwh.model.advanced.Bid;
import org.jpwh.model.advanced.Item;
import org.jpwh.model.advanced.ItemBidSummary;
import org.testng.annotations.Test; import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.transaction.UserTransaction;
import java.math.BigDecimal; import static org.testng.Assert.assertEquals; public class MappedSubselect extends JPATest { @Override
public void configurePersistenceUnit() throws Exception {
configurePersistenceUnit("AdvancedPU");
} @Test
public void loadSubselectEntity() throws Exception {
long ITEM_ID = storeItemAndBids(); UserTransaction tx = TM.getUserTransaction();
try {
tx.begin();
EntityManager em = JPA.createEntityManager(); {
ItemBidSummary itemBidSummary = em.find(ItemBidSummary.class, ITEM_ID);
// select * from (
// select i.ID as ITEMID, i.ITEM_NAME as NAME, ...
// ) where ITEMID = ? assertEquals(itemBidSummary.getName(), "AUCTION: Some item");
}
em.clear(); { // Hibernate will synchronize the right tables before querying
Item item = em.find(Item.class, ITEM_ID);
item.setName("New name"); // No flush before retrieval by identifier!
//ItemBidSummary itemBidSummary = em.find(ItemBidSummary.class, ITEM_ID); // Automatic flush before queries if synchronized tables are affected!
Query query = em.createQuery(
"select ibs from ItemBidSummary ibs where ibs.itemId = :id"
);
ItemBidSummary itemBidSummary =
(ItemBidSummary)query.setParameter("id", ITEM_ID).getSingleResult(); assertEquals(itemBidSummary.getName(), "AUCTION: New name");
} tx.commit();
em.close();
} finally {
TM.rollback();
}
} public Long storeItemAndBids() throws Exception {
UserTransaction tx = TM.getUserTransaction();
tx.begin();
EntityManager em = JPA.createEntityManager();
Item item = new Item();
item.setName("Some item");
item.setDescription("This is some description.");
em.persist(item);
for (int i = 1; i <= 3; i++) {
Bid bid = new Bid();
bid.setAmount(new BigDecimal(10 + i));
bid.setItem(item);
em.persist(bid);
}
tx.commit();
em.close();
return item.getId();
} }
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.
package org.jpwh.model.advanced; import org.jpwh.model.Constants; import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.sql.Blob;
import java.util.Date; @Entity
public class Item { /*
The <code>Item</code> entity defaults to field access, the <code>@Id</code> is on a field. (We
have also moved the brittle <code>ID_GENERATOR</code> string into a constant.)
*/
@Id
@GeneratedValue(generator = Constants.ID_GENERATOR)
protected Long id; @org.hibernate.annotations.Type(type = "yes_no")
protected boolean verified = false; // JPA says @Temporal is required but Hibernate will default to TIMESTAMP without it
@Temporal(TemporalType.TIMESTAMP)
@Column(updatable = false)
@org.hibernate.annotations.CreationTimestamp
protected Date createdOn; // Java 8 API
// protected Instant reviewedOn; @NotNull
@Basic(fetch = FetchType.LAZY) // Defaults to EAGER
protected String description; @Basic(fetch = FetchType.LAZY)
@Column(length = 131072) // 128 kilobyte maximum for the picture
protected byte[] image; // Maps to SQL VARBINARY type @Lob
protected Blob imageBlob; @NotNull
@Enumerated(EnumType.STRING) // Defaults to ORDINAL
protected AuctionType auctionType = AuctionType.HIGHEST_BID; @org.hibernate.annotations.Formula(
"substr(DESCRIPTION, 1, 12) || '...'"
)
protected String shortDescription; @org.hibernate.annotations.Formula(
"(select avg(b.AMOUNT) from BID b where b.ITEM_ID = ID)"
)
protected BigDecimal averageBidAmount; @Column(name = "IMPERIALWEIGHT")
@org.hibernate.annotations.ColumnTransformer(
read = "IMPERIALWEIGHT / 2.20462",
write = "? * 2.20462"
)
protected double metricWeight; @Temporal(TemporalType.TIMESTAMP)
@Column(insertable = false, updatable = false)
@org.hibernate.annotations.Generated(
org.hibernate.annotations.GenerationTime.ALWAYS
)
protected Date lastModified; @Column(insertable = false)
@org.hibernate.annotations.ColumnDefault("1.00")
@org.hibernate.annotations.Generated(
org.hibernate.annotations.GenerationTime.INSERT
)
protected BigDecimal initialPrice; /*
The <code>@Access(AccessType.PROPERTY)</code> setting on the <code>name</code> field switches this
particular property to runtime access through getter/setter methods by the JPA provider.
*/
@Access(AccessType.PROPERTY)
@Column(name = "ITEM_NAME") // Mappings are still expected here!
protected String name; /*
Hibernate will call <code>getName()</code> and <code>setName()</code> when loading and storing items.
*/
public String getName() {
return name;
} public void setName(String name) {
this.name =
!name.startsWith("AUCTION: ") ? "AUCTION: " + name : name;
} public Long getId() { // Optional but useful
return id;
} public String getDescription() {
return description;
} public void setDescription(String description) {
this.description = description;
} public String getShortDescription() {
return shortDescription;
} public BigDecimal getAverageBidAmount() {
return averageBidAmount;
} public double getMetricWeight() {
return metricWeight;
} public void setMetricWeight(double metricWeight) {
this.metricWeight = metricWeight;
} public Date getLastModified() {
return lastModified;
} public BigDecimal getInitialPrice() {
return initialPrice;
} public Date getCreatedOn() {
return createdOn;
} public boolean isVerified() {
return verified;
} public void setVerified(boolean verified) {
this.verified = verified;
} public byte[] getImage() {
return image;
} public void setImage(byte[] image) {
this.image = image;
} public Blob getImageBlob() {
return imageBlob;
} public void setImageBlob(Blob imageBlob) {
this.imageBlob = imageBlob;
} public AuctionType getAuctionType() {
return auctionType;
} public void setAuctionType(AuctionType auctionType) {
this.auctionType = auctionType;
}
}
3.
package org.jpwh.model.advanced; import org.jpwh.model.Constants; import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal; @Entity
@org.hibernate.annotations.Immutable
public class Bid { @Id
@GeneratedValue(generator = Constants.ID_GENERATOR)
protected Long id; @NotNull
protected BigDecimal amount; @ManyToOne(optional = false, fetch = FetchType.LAZY) // NOT NULL
@JoinColumn(name = "ITEM_ID") // Actually the default name
protected Item item; public Long getId() {
return id;
} public BigDecimal getAmount() {
return amount;
} public void setAmount(BigDecimal amount) {
this.amount = amount;
} public Item getItem() {
return item;
} public void setItem(Item item) {
this.item = item;
}
}
JavaPersistenceWithHibernate第二版笔记-第四章-Mapping persistent classes-003映射实体时的可选操作(<delimited-identifiers/>、PhysicalNamingStrategy、PhysicalNamingStrategyStandardImpl、、、)的更多相关文章
- JavaPersistenceWithHibernate第二版笔记-第四章-Mapping persistent classes-002identity详解
一.简介 1.You now have three methods for distinguishing references: Objects are identical if they occ ...
- JavaPersistenceWithHibernate第二版笔记-第四章-Mapping persistent classes-001区分entities and value types
一.介绍 1.这种引用方式不对,但删除时不能级联 要这种引用方式 2.The Bid class could be a problem. In object-oriented modeling, th ...
- JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-005控制类型映射(Nationalized、@LOB、@org.hibernate.annotations.Type)
一.简介 1. 2. 3. 4. to override this default mapping. The JPA specification has a convenient shortcut a ...
- JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-001Mapping basic properties(@Basic、@Access、access="noop"、@Formula、@ColumnTransformer、@Generated、 @ColumnDefaul、@Temporal、@Enumerated)
一.简介 在JPA中,默认所有属性都会persist,属性要属于以下3种情况,Hibernate在启动时会报错 1.java基本类型或包装类 2.有注解 @Embedded 3.有实现java.io. ...
- 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 ...
- 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 ...
- JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-002Table per concrete class with implicit polymorphism(@MappedSuperclass、@AttributeOverride)
一.结构 二.代码 1. package org.jpwh.model.inheritance.mappedsuperclass; import javax.persistence.MappedSup ...
- 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 ...
- 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 ...
随机推荐
- wire与reg的区别?转载大神!
本文转自:http://www.cnblogs.com/thymon/archive/2010/06/09/1754541.html //------------------------------- ...
- Labview实现脉波调制( PDM )
Labview实现脉波调制( PDM ) 根据定义为脉冲宽度调制 生成一个正弦信号,得到其幅值输入给一个方波信号的占空比 由于方波信号的占空比里面含有正弦信号的信息 因此通过滤出方波信号的占空比信息则 ...
- urllib3 ProxyManager
ProxyManager is an HTTP proxy-aware subclass of PoolManager. It produces a singleHTTPConnectionPool ...
- Notes of the scrum meeting(11/2)
meeting time:13:00~13:30p.m.,November 2nd,2013 meeting place:3号公寓楼一层 attendees: 顾育豪 ...
- BICEP单元测试计划——四则运算Ⅱ
一.测试方法(Right-BICEP) 6个值得测试的具体部位: Right-结果是否正确? B-是否所有的边界条件都是正确的? I-能查一下反向关联吗? C-能用其他手段交叉检查一下结果吗? E-你 ...
- VLC编译问题
在Ubuntu下编译VLC源代码生成的VLC无法播放Youtube视频(比如https://www.youtube.com/watch?v=mDp-ABzpRX8) 错误提示如下: zlf@ubunt ...
- Ubuntu 下编译安装linux
1. 准备工作切换为管理员权限,sudo –i 输入用户密码 进入root 权限apt-get install build-essential kernel-package libncurses5-d ...
- UVA 10004 Bicoloring
题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=12&pa ...
- 【BZOJ】【3831】【POI2014】Little Bird
DP/单调队列优化 水题水题水题水题 单调队列优化的线性dp…… WA了8次QAQ,就因为我写队列是[l,r),但是实际操作取队尾元素的时候忘记了……不怎么从队尾取元素嘛……平时都是直接往进放的……还 ...
- Leetcode#150 Evaluate Reverse Polish Notation
原题地址 基本栈操作. 注意数字有可能是负的. 代码: int toInteger(string &s) { ; ] == '-' ? true : false; : ; i < s.l ...