国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

Hibernate問(wèn)題集錦

niceforbear / 1578人閱讀

摘要:查詢(xún)照樣寫(xiě)就行,如下參考問(wèn)題七中關(guān)于多表連接查詢(xún)和返回值集合中對(duì)象問(wèn)題錯(cuò)誤的查詢(xún)語(yǔ)句釋放分析原來(lái)是查詢(xún)出來(lái)的字段并不能自動(dòng)轉(zhuǎn)換為對(duì)象。參考問(wèn)題八原因原生的語(yǔ)句中返回值為,而語(yǔ)句中的返回值位型的,網(wǎng)上說(shuō)的主要是兼容而做的。

首先奉上
Hibernate3.2 API地址:http://docs.jboss.org/hiberna...
Hibernate4.3 API地址:http://docs.jboss.org/hiberna...
Hibernate 4.3文檔:http://hibernate.org/orm/docu...

問(wèn)題一、No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

情景0:請(qǐng)?jiān)O(shè)置OpenSessionInViewFilter

情景1:在service外使用了dao.getSession()從而導(dǎo)致問(wèn)題。

解決思路:
其實(shí)我的Service層是加了@Transactional注解的,但是由于某些原因,在service外使用了dao.getSession()從而導(dǎo)致該問(wèn)題。
問(wèn)題代碼如下:(這段代碼沒(méi)有放在被@Transactional注解的Serivce層,從而導(dǎo)致問(wèn)題)

Criteria c=storeDao.getSession().createCriteria(Store.class).add(Restrictions.or(Restrictions.isNull("mainImgJson"),Restrictions.isNull("introImgJson")));
c.createAlias("terrace", "terrace").add(Restrictions.eq("terrace.keyId", "1"));
c.addOrder(Order.desc("updateTime"));
Page page=storeManager.findPage(c, 1, 100);

解決方法就是在這段代碼調(diào)用方法上加上@Transactional注解。
參考:http://stackoverflow.com/ques...
當(dāng)然此處更好的辦法是采用DetachedCriteria

情景2:Service[抽象]父類(lèi)數(shù)據(jù)庫(kù)方法沒(méi)有加@Transactional
假設(shè)有以下類(lèi):

@Transactional
public class SubClass extends SuperClass {

    public void loadDb(){
//數(shù)據(jù)庫(kù)操作
    }

}
public class SuperClass {

    public void savedb() {
//數(shù)據(jù)庫(kù)操作
    }
}

savedb是父類(lèi)的方法,loadDb是子類(lèi)的方法。如果有以下調(diào)用:

@Test
public void test(){
    SubClass o = new SubClass();
    o.savedb();//將會(huì)報(bào)沒(méi)有Session的錯(cuò)誤
    o.loadDb();//正常
}

解決方法:在父類(lèi)中標(biāo)注@Transactional(父類(lèi)是抽象類(lèi)也可以):

@Transactional
public class SuperClass {

    public void savedb() {

    }
}

參考:http://www.cnblogs.com/xiefei...

情景3:其他場(chǎng)景終極解決方案:

有可能是在非請(qǐng)求線程(請(qǐng)求線程有openssessioninviewfilter把控)某些查詢(xún)延遲加載導(dǎo)致的.
對(duì)于這種情形,
第一:你可以設(shè)置lazy=false,不過(guò)很多情況下不現(xiàn)實(shí);
第二:對(duì)于需要后續(xù)的數(shù)據(jù),查詢(xún)出來(lái)之后立即get(),或者size(),這樣就能觸發(fā)查詢(xún)。還可以使用Hibernate.initialize方法

在使用hibernate進(jìn)行持久化時(shí),有時(shí)需要?jiǎng)討B(tài)的改變對(duì)象的加載,比如在編輯頁(yè)面里面lazy=true,而在瀏覽頁(yè)面lazy=false,這樣可以在需要lazy的地方才進(jìn)行控制。而配置文件中Lazy屬性是全局控制的,如何處理呢?
  當(dāng)元素或者元素的lazy屬性為true時(shí),load() or get() or
find()加載這些對(duì)象時(shí),Hibernate不會(huì)馬上產(chǎn)生任何select語(yǔ)句,只是產(chǎn)生一個(gè)Obj代理類(lèi)實(shí)例,只有在session沒(méi)有關(guān)閉的情況下運(yùn)行Obj.getXxx()時(shí)才會(huì)執(zhí)行select語(yǔ)句從數(shù)據(jù)庫(kù)加載對(duì)象,如果沒(méi)有運(yùn)行任何Obj.getXxx()方法,而session已經(jīng)關(guān)閉,Obj已成游離狀態(tài),此時(shí)再運(yùn)行Obj.getXxx()方法,Hibernate就會(huì)拋出"Could
not initialize proxy - the owning Session was
closeed"的異常,是說(shuō)Obj代理類(lèi)實(shí)例無(wú)法被初始化。然而想在Session關(guān)閉之前不調(diào)用Obj.getXxx()方法而關(guān)閉Session之后又要用,此時(shí)只要在Session關(guān)閉之前調(diào)用Hibernate.initialize(Obj)或者Hibernate.initialize(Obj.getXxx())即可,net.sf.hibernate.Hibernate類(lèi)的initialize()靜態(tài)方法用于在Session范圍內(nèi)顯示初始化代理類(lèi)實(shí)例。
  在配置文件里面可以用lazy=true,在程序里面可以用強(qiáng)制加載的方法Hibernate.initialize(Object
proxy) 方法強(qiáng)制加載這樣就相當(dāng)于動(dòng)態(tài)改變?yōu)閘azy=false。
  但在使用時(shí)需要注意的一點(diǎn)是:其中的proxy是持久對(duì)象的關(guān)聯(lián)對(duì)象屬性,比如A實(shí)體,你要把A的關(guān)聯(lián)實(shí)體B也檢出,則要寫(xiě)Hibernate.initialize(a.b)。

Hibernate 4.2之后,你還可以配置hibernate.enable_lazy_load_no_trans:
hibernate.xml:
true

Sinche Hibernate 4.2 you can use
.setProperty("hibernate.enable_lazy_load_no_trans", "true"); this
option solves the dreaded org.hibernate.LazyInitializationException:
could not initialize proxy - no Session which took so many hours of
life to programmers away.

具體可以看https://docs.jboss.org/hibern...

對(duì)于使用HQL的童鞋,可以顯式join fetch

Query query = session.createQuery(
    "from Model m " +
    "join fetch m.modelType " +
    "where modelGroup.id = :modelGroupId"
);

第三:查詢(xún)時(shí)動(dòng)態(tài)設(shè)置立即join,比如

crit.setFetchMode("pays", FetchMode.JOIN);
crit.setFetchMode("ville", FetchMode.JOIN);
crit.setFetchMode("distination", FetchMode.JOIN);

第三部分總結(jié):

0、在場(chǎng)景為Request請(qǐng)求線程時(shí),配置Open Session in View 具體原理,請(qǐng)看https://vladmihalcea.com/2016...
1、使用HQL時(shí)可以join fetch (推薦);或者你也可以用uniqueResult()方法,該方法會(huì)立即查出關(guān)聯(lián)對(duì)象。
2、使用criteria時(shí)可以FetchMode.JOIN
3、顯式調(diào)用Hibernate.initialize(obj),Hibernate.initialize(obj.getXXX())
4、配置hibernate.enable_lazy_load_no_trans:(使用時(shí)請(qǐng)注意開(kāi)銷(xiāo))

hibernate.xml:
true
 persistence.xml:

解釋請(qǐng)參考:https://vladmihalcea.com/2016...
但是,使用hibernate.enable_lazy_load_no_trans配置時(shí),你需要注意下面這一點(diǎn):

Behind the scenes, a temporary Session is opened just for initializing
every post association. Every temporary Session implies acquiring a
new database connection, as well as a new database transaction.

The more association being loaded lazily, the more additional
connections are going to be requested which puts pressure on the
underlying connection pool. Each association being loaded in a new
transaction, the transaction log is forced to flush after each
association initialization

翻譯一下就是:這種情形下,每次初始化一個(gè)實(shí)體的關(guān)聯(lián)就會(huì)創(chuàng)建一個(gè)臨時(shí)的session來(lái)加載,每個(gè)臨時(shí)的session都會(huì)獲取一個(gè)臨時(shí)的數(shù)據(jù)庫(kù)連接,開(kāi)啟一個(gè)新的事物。這就導(dǎo)致對(duì)底層連接池壓力很大,而且事物日志也會(huì)被每次flush.
設(shè)想一下:假如我們查詢(xún)了一個(gè)分頁(yè)list每次查出1000條,這個(gè)實(shí)體有三個(gè)lazy關(guān)聯(lián)對(duì)象,那么,恭喜你,你至少需要?jiǎng)?chuàng)建3000個(gè)臨時(shí)session+connection+transaction.

5、使用 DTO projection (推薦):解釋請(qǐng)參考https://vladmihalcea.com/2016...
其實(shí)就是定義一個(gè)多帶帶的DTO來(lái)保存查詢(xún)結(jié)果。

public class PostCommentDTO {
    private final Long id;
 
    private final String review;
 
    private final String title;
 
    public PostCommentDTO(
        Long id, String review, String title) {
        this.id = id;
        this.review = review;
        this.title = title;
    }
 
    public Long getId() {
        return id;
    }
 
    public String getReview() {
        return review;
    }
 
    public String getTitle() {
        return title;
    }
}
List comments = doInJPA(entityManager -> {
    return entityManager.createQuery(
        "select new " +
        "   com.vladmihalcea.book.hpjp.hibernate.fetching.PostCommentDTO(" +
        "       pc.id, pc.review, p.title" +
        "   ) " +
        "from PostComment pc " +
        "join pc.post p " +
        "where pc.review = :review", PostCommentDTO.class)
    .setParameter("review", review)
    .getResultList();
});
 
for(PostCommentDTO comment : comments) {
    LOGGER.info("The post title is "{}"", comment.getTitle());
}

參考:http://stackoverflow.com/ques...

第四:如果由于某些要求,你不能按以上操作進(jìn)行:那么請(qǐng)看終極解決方案:

/**
 * 由于在http請(qǐng)求線程之外,openssessioninviewfilter不起作用,導(dǎo)致線程沒(méi)有綁定session,這個(gè)類(lèi)就是為了解決此問(wèn)題。
 * 自己管理Hibernate Session的Runnable。
 * @author taojw
 */
public abstract class TxSessionRunnable implements Runnable {
    @Override
    public final void run(){
        SessionFactory sessionFactory = (SessionFactory)SpringContextHolder.getApplicationContext().getBean("sessionFactory");  
        boolean participate = bindHibernateSessionToThread(sessionFactory); 
        try{
            execute();
        }finally{
            closeHibernateSessionFromThread(participate, sessionFactory);
        }
    }
    public void execute(){
        
    }
    public static boolean bindHibernateSessionToThread(SessionFactory sessionFactory) {  
        if (TransactionSynchronizationManager.hasResource(sessionFactory)) {  
            // Do not modify the Session: just set the participate flag.  
            return true;  
        } else {  
            Session session = sessionFactory.openSession();  
            session.setFlushMode(FlushMode.MANUAL);  
            SessionHolder sessionHolder = new SessionHolder(session);  
            TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder);  
        }  
        return false;  
    }  
    public static void closeHibernateSessionFromThread(boolean participate, Object sessionFactory) {  
        if (!participate) {  
            SessionHolder sessionHolder = (SessionHolder)TransactionSynchronizationManager.unbindResource(sessionFactory);  
            SessionFactoryUtils.closeSession(sessionHolder.getSession());  
        }  
    }

}

參考
http://stackoverflow.com/ques...
http://blog.csdn.net/zhengwei...
http://stackoverflow.com/ques...

no session問(wèn)題補(bǔ)充:延遲加載時(shí),Hibernate initialize object in another session ?

可以不可以先獲取一個(gè)延遲加載的對(duì)象,不立即調(diào)用Hibernate.initialize,而關(guān)閉session,然后在需要的時(shí)候,打開(kāi)另外一個(gè)session,調(diào)用Hibernate.initialize來(lái)初始化延遲的對(duì)象呢?
答案是否定的。不可以!
參考:https://stackoverflow.com/que...
Entity objects are pretty much "bound" to original session where they were fetched and queries like this cannot be performed in this way. One solution is to bound entity to new session calling session.update(entity) and than this new session knows about entity. Basically new query is issued to populate entity fields again.
So avoid this if not necessary and try to fetch all needed data in original session
或者你也可以通過(guò)獲取主鍵去再次主動(dòng)查詢(xún)關(guān)聯(lián)對(duì)象

問(wèn)題二、No row with the given identifier exists

產(chǎn)生此問(wèn)題的原因:
有兩張表,table1和table2.產(chǎn)生此問(wèn)題的原因就是table1里做了關(guān)聯(lián)或者(特殊的多對(duì)一映射,實(shí)際就是一對(duì)一)來(lái)關(guān)聯(lián)table2.當(dāng)hibernate查找的時(shí)候,table2里的數(shù)據(jù)沒(méi)有與table1相匹配的,這樣就會(huì)報(bào)No row with the given identifier exists這個(gè)錯(cuò).
注解配置解決方法:
使用hibernate 注解配置實(shí)體類(lèi)的關(guān)聯(lián)關(guān)系,在many-to-one,one-to-one關(guān)聯(lián)中,一邊引用自另一邊的屬性,如果屬性值為某某的數(shù)據(jù)在數(shù)據(jù)庫(kù)不存在了,hibernate默認(rèn)會(huì)拋出異常。解決此問(wèn)題,加上如下注解就可以了:
@NotFound(action=NotFoundAction.IGNORE),意思是找不到引用的外鍵數(shù)據(jù)時(shí)忽略,NotFound默認(rèn)是exception

@ManyToOne(fetch = FetchType.LAZY)    
    @JoinColumn(name = "ICT_BASE_ID", referencedColumnName = "ID", unique = false, nullable = false, insertable = false, updatable = false)    
    @NotFound(action=NotFoundAction.IGNORE)    
    public IctBase getIctBase() {    
        return ictBase;    
    }

參考:http://blog.csdn.net/h3960710...
http://www.cnblogs.com/rixian...

問(wèn)題三、How to autogenerate created or modified timestamp field?

Hibernate4.3之后,我們可以直接使用JPA注解:"@CreationTimestamp" and "@UpdateTimestamp"

protected Date insertTime;
    protected Date updateTime;
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(updatable = false)  
    @CreationTimestamp
    public Date getInsertTime() {
        return insertTime;
    }
    public void setInsertTime(Date insertTime) {
        this.insertTime = insertTime;
    }
    @UpdateTimestamp
    @Temporal(TemporalType.TIMESTAMP)
    public Date getUpdateTime() {
        return updateTime;
    }
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

如果使用之前版本,那么你可以給dao封裝一個(gè)save方法,并規(guī)定inserttime,updatetime字段名。統(tǒng)一處理即可。

參考:http://stackoverflow.com/ques...
http://stackoverflow.com/ques...

問(wèn)題四、hibernate的速度問(wèn)題之fetch_size和batch_size

hibernate的速度性能并不差,當(dāng)然了這和應(yīng)用的數(shù)據(jù)庫(kù)有關(guān),在Oracle上,hibernate支持 hibernate.jdbc.fetch_size和 hibernate.jdbc.batch_size,而MySQL卻不支持,而我原來(lái)的項(xiàng)目絕大多數(shù)都是使用MySQL的,所以覺(jué)得速度慢,其實(shí)在企業(yè)級(jí)應(yīng)用,尤其是金融系統(tǒng)大型應(yīng)用上,使用Oracle比較多,相對(duì)來(lái)說(shuō),hibernate會(huì)提升系統(tǒng)很多性能的。
hibernate.jdbc.fetch_size 50 //讀
hibernate.jdbc.batch_size 30 //寫(xiě)
hiberante.cfg.xml(Oracle ,sql server 支持,mysql不支持)

50
30

這兩個(gè)選項(xiàng)非常非常非常重要!!!將嚴(yán)重影響Hibernate的CRUD性能!
Fetch Size 是設(shè)定JDBC的Statement讀取數(shù)據(jù)的時(shí)候每次從數(shù)據(jù)庫(kù)中取出的記錄條數(shù)。
例如一次查詢(xún)1萬(wàn)條記錄,對(duì)于Oracle的JDBC驅(qū)動(dòng)來(lái)說(shuō),是不會(huì)1次性把1萬(wàn)條取出來(lái)的,而只會(huì)取出Fetch Size條數(shù),當(dāng)紀(jì)錄集遍歷完了這些記錄以后,再去數(shù)據(jù)庫(kù)取Fetch Size條數(shù)據(jù)。
因此大大節(jié)省了無(wú)謂的內(nèi)存消耗。當(dāng)然Fetch Size設(shè)的越大,讀數(shù)據(jù)庫(kù)的次數(shù)越少,速度越快;Fetch Size越小,讀數(shù)據(jù)庫(kù)的次數(shù)越多,速度越慢。 但內(nèi)存消耗正好相反
建議使用Oracle的一定要將Fetch Size設(shè)到50
不過(guò)并不是所有的數(shù)據(jù)庫(kù)都支持Fetch Size特性,例如MySQL就不支持

Batch Size是設(shè)定對(duì)數(shù)據(jù)庫(kù)進(jìn)行批量刪除,批量更新和批量插入的時(shí)候的批次大小,有點(diǎn)相當(dāng)于設(shè)置Buffer緩沖區(qū)大小的意思。
Batch Size越大,批量操作的向數(shù)據(jù)庫(kù)發(fā)送sql的次數(shù)越少,速度就越快。!

參考:http://blog.csdn.net/rick_123...

問(wèn)題五、@UniqueConstraint and @Column(unique = true)的區(qū)別

比如

@Table(
   name = "product_serial_group_mask", 
   uniqueConstraints = {@UniqueConstraint(columnNames = {"mask", "group"})}
)

And

@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private ProductSerialMask mask;

@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private Group group;

區(qū)別在哪里?

前者是聯(lián)合約束、后者分別是獨(dú)立約束。

參考:http://stackoverflow.com/ques...

問(wèn)題六、HQL如何進(jìn)行多對(duì)多查詢(xún)

比如多對(duì)多時(shí),Book有個(gè)Set類(lèi)型屬性,Author有個(gè)Set的屬性。其實(shí)你不用管authors是Set類(lèi)型。查詢(xún)照樣寫(xiě)就行,如下:

select a.firstName, a.lastName from Book b join b.authors a where b.id = :id

參考:http://stackoverflow.com/ques...
http://www.cnblogs.com/kingxi...

問(wèn)題七、Hibernate中關(guān)于多表連接查詢(xún)hql 和 sql 返回值集合中對(duì)象問(wèn)題

錯(cuò)誤的查詢(xún)語(yǔ)句:

String sql = "select a.* from tb_doc_catalog a where a.cat_code like ""+catCode+"%"";
Session session = this.getSession();
try {
List catNameList = session.createSQLQuery(sql).list();
return catNameList ;
} finally {
releaseSession(session); //釋放session
}

分析:原來(lái)是查詢(xún)出來(lái)的字段并不能自動(dòng)轉(zhuǎn)換為bean對(duì)象

解決思路一(采用hql查詢(xún)):

String sql = "select a from DocCatalogInfo a where a.catCode like ""+catCode+"%"";
List catNameList =getHibernateTemplate().find(sql);
return catNameList ;

ok,測(cè)試一下沒(méi)問(wèn)題。

解決思路二(采用原生sql查詢(xún)):

String sql = "select a.* from tb_doc_catalog a where a.cat_code like ""+catCode+"%"";
Session session = this.getSession();
try {
List catNameList = session.createSQLQuery(sql).addEntity(DocCatalogInfo.class).list();
return catNameList ;
} finally {
releaseSession(session); //釋放session
}

ok。

hibernate 中createQuery與createSQLQuery兩者區(qū)別是:
前者用的hql語(yǔ)句進(jìn)行查詢(xún),后者可以用sql語(yǔ)句查詢(xún)
前者以hibernate生成的Bean為對(duì)象裝入list返回 ,后者則是以對(duì)象數(shù)組進(jìn)行存儲(chǔ)

其實(shí),createSQLQuery有一個(gè)addEntity方法可以直接轉(zhuǎn)換對(duì)象

Query query = session.createSQLQuery(sql).addEntity(XXXXXXX.class);

對(duì)于連接了多個(gè)表的查詢(xún),可能在多個(gè)表中出現(xiàn)同樣名字的字段。下面的方法就可以避免字段名重復(fù)的問(wèn)題:

List cats = sess.createSQLQuery( " select {cat.*} from cats cat " ).addEntity( " cat " , Cat. class ).list(); 

addEntity()方法將SQL表的別名和實(shí)體類(lèi)聯(lián)系起來(lái),并且確定查詢(xún)結(jié)果集的形態(tài)。
addJoin()方法可以被用于載入其他的實(shí)體和集合的關(guān)聯(lián).

List cats = sess.createSQLQuery(
" select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id " )
.addEntity( " cat " , Cat. class )
.addJoin( " kitten " , " cat.kittens " )
.list(); 

原生的SQL查詢(xún)可能返回一個(gè)簡(jiǎn)單的標(biāo)量值或者一個(gè)標(biāo)量和實(shí)體的結(jié)合體。

Double max = (Double) sess.createSQLQuery( " select max(cat.weight) as maxWeight from cats cat " )
.addScalar( " maxWeight " , Hibernate.DOUBLE);
.uniqueResult(); 

命名SQL查詢(xún)
@NamedQuery("persons")

List people = sess.getNamedQuery( "persons" ).setString( " namePattern " , namePattern)
.setMaxResults( 50 )
.list(); 

返回一個(gè)Map對(duì)象,代碼如下

Query query = session.createSQLQuery("select id,name from Tree t where pid in (select id from Tree) ").setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); //返回一個(gè)map,KEY:為DB中名稱(chēng)一致(大小寫(xiě)一致)遍歷list時(shí)就可以
Map map = (Map)list.get[i];

map.get("id");map.get("name");來(lái)取值。按你的SQL語(yǔ)句select后的字段名來(lái)作為map的Key,但這個(gè)key必須與數(shù)據(jù)庫(kù)中的字段名一模一樣。

參考:http://blog.csdn.net/stonejon...

問(wèn)題八、hibernate:java.math.BigInteger cannot be cast to java.lang.Long
Query query1 = session.createSQLQuery("select count(*) from user u where u.name like ? ").setParameter(0, "%lis%") ;

Query query2 = session.createQuery("select count(*) from User ") ;

Sysstem.out.println((Long) query1.list().get(0)) ; //wrong
Sysstem.out.println((Long) query2.list().get(0)) ; //right

原因:原生的SQL語(yǔ)句中count()返回值為BigInteger,而HQL語(yǔ)句中的count()返回值位Long型的,網(wǎng)上說(shuō)的主要是兼容JPA而做的。
當(dāng)使用createSQLQuery時(shí),其返回值為BigInteger類(lèi)型;
當(dāng)使用createQuery時(shí),其返回值位Long型的。
解決:

public long getMusicCount(long id){
        String sql="select count(1) from music_singer_music where mid=?";
        Object obj=dao.getSession().createSQLQuery(sql).setParameter(0, id).uniqueResult();
        if(obj instanceof Long){
            return (Long)obj;
        }else if(obj instanceof BigInteger){
            return ((BigInteger)obj).longValue();
        }
        return 0;
    }

參考:http://blog.csdn.net/u0137625...

Hibernate陷阱之Session清空緩存時(shí)機(jī)

清空緩存

當(dāng)調(diào)用session.evict(customer); 或者session.clear(); 或者session.close()方法時(shí),Session的緩存被清空。

清理緩存

Session具有一個(gè)緩存,位于緩存中的對(duì)象處于持久化狀態(tài),它和數(shù)據(jù)庫(kù)中的相關(guān)記錄對(duì)應(yīng),Session能夠在某些時(shí)間點(diǎn),按照緩存中持久化對(duì)象的屬性變化來(lái)同步更新數(shù)據(jù)庫(kù),這一過(guò)程被稱(chēng)為清理緩存。

在默認(rèn)情況下,Session會(huì)在下面的時(shí)間點(diǎn)清理緩存。

當(dāng)應(yīng)用程序調(diào)用org.hibernate.Transaction的commit()方法的時(shí)候,commit()方法先清理緩存,然后在向數(shù)據(jù)庫(kù)提交事務(wù);

當(dāng)應(yīng)用程序調(diào)用Session的list()或者iterate()時(shí)(【注】get()和load()方法不行),如果緩存中持久化對(duì)象的屬性發(fā)生了變化,就會(huì)先清理緩存,以保證查詢(xún)結(jié)果能能反映持久化對(duì)象的最新?tīng)顟B(tài);

當(dāng)應(yīng)用程序顯式調(diào)用Session的flush()方法的時(shí)候。

上面第二點(diǎn)解釋了為什么在list()查詢(xún)是有個(gè)時(shí)候會(huì)出現(xiàn)update語(yǔ)句。

http://blog.csdn.net/xwz0528/...

hibernate中g(shù)etCurrentSession()和openSession()區(qū)別

1 getCurrentSession創(chuàng)建的session會(huì)和綁定到當(dāng)前線程,而openSession每次創(chuàng)建新的session。
2 getCurrentSession創(chuàng)建的線程會(huì)在事務(wù)回滾或事物提交后自動(dòng)關(guān)閉,而openSession必須手動(dòng)關(guān)閉
在一個(gè)應(yīng)用程序中,如果DAO 層使用Spring 的hibernate 模板,通過(guò)Spring 來(lái)控制session 的生命周期,則首選getCurrentSession()。
在 SessionFactory 啟動(dòng)的時(shí)候, Hibernate 會(huì)根據(jù)配置創(chuàng)建相應(yīng)的 CurrentSessionContext ,在 getCurrentSession() 被調(diào)用的時(shí)候,實(shí)際被執(zhí)行的方法是 CurrentSessionContext.currentSession() 。

Hibernate4之后與Spring結(jié)合需配置為

org.springframework.orm.hibernate4.SpringSessionContext

在 getCurrentSession() 被調(diào)用的時(shí)候,實(shí)際被執(zhí)行的方法是 SpringSessionContext.currentSession()

實(shí)體對(duì)象為什么需要覆蓋equals與hashCode

讓我設(shè)想以下情景:

Session s1=sessionFactory.openSession();
s1.beginTransaction();
Object a=s1.get(Item.class,new Long(123));
Object b=s1.get(Item.class,new Long(123));

// a==b為true,a、b指向相同的內(nèi)存地址。

s1.getTransaction.commit();
s1.close();

Session s2=sessionFactory.openSession();
s2.beginTransaction();
Object c=s2.get(Item.class,new Long(123));

//a==c返回false,a,c指向不同的內(nèi)存地址

s2.getTransaction.commit();
s2.close();

/*現(xiàn)在a,b,c都處于脫管狀態(tài)/
Set set=new HashSet();
set.add(a);
set.add(b);
set.add(c);

/*輸出什么呢?1?,2?,3?/
System.out.println(set.size())
我們知道set是通過(guò)調(diào)用集合元素的equals方法來(lái)確保元素唯一性的。而Object的equals方法默認(rèn)就是通過(guò)obj1==obj2來(lái)通過(guò)內(nèi)存地址判斷同一性。
那我們現(xiàn)在知道了把。上述會(huì)輸出2。但是我們知道這兩個(gè)元素都是代表數(shù)據(jù)褲中的同一行。所以這個(gè)時(shí)候我們就需要覆蓋equals與hashCode方法了。建議我們對(duì)所有的實(shí)體類(lèi)都覆蓋這兩個(gè)方法,因?yàn)槲覀儫o(wú)法保證這種情況不會(huì)發(fā)生。

覆蓋實(shí)體類(lèi)的equals方法可以選擇兩種方式:

1、通過(guò)判斷業(yè)務(wù)鍵而非數(shù)據(jù)庫(kù)主鍵的相等性。如果業(yè)務(wù)鍵是唯一的話,推薦此方式。

2、通過(guò)判斷對(duì)象的所有屬性的相等性。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/67068.html

相關(guān)文章

  • hibernate學(xué)習(xí)概要

    摘要:一中實(shí)體規(guī)則實(shí)體類(lèi)創(chuàng)建的注意事項(xiàng)持久化類(lèi)提供無(wú)參數(shù)構(gòu)造成員變量私有,提供方法訪問(wèn),需提供屬性屬性就是方法持久化類(lèi)中的屬性,應(yīng)盡量使用包裝類(lèi)型可以表示,在插如數(shù)據(jù)庫(kù)中有作用持久化類(lèi)需要提供主鍵屬性與數(shù)據(jù)庫(kù)中主鍵列對(duì)應(yīng)不需要修飾原因使用代理生成 一、hibernate中實(shí)體規(guī)則 實(shí)體類(lèi)創(chuàng)建的注意事項(xiàng) 1.持久化類(lèi)提供無(wú)參數(shù)構(gòu)造2.成員變量私有,提供get、set方法訪問(wèn),需提供屬性(屬性就...

    Noodles 評(píng)論0 收藏0
  • Hibernate 自定義表名映射

    摘要:所以設(shè)計(jì)的表名映射格式為,如果不加注解,則將實(shí)體名按照默認(rèn)的生成規(guī)則進(jìn)行生成,如果加了注解,則填寫(xiě)的就作為表名映射,不進(jìn)行任何處理。云智命名策略實(shí)體與數(shù)據(jù)表名的關(guān)系配置然后將該項(xiàng)配置修改為我們自己建立的實(shí)現(xiàn)類(lèi)。 問(wèn)題描述 Hibernate映射介紹 Hibernate中,默認(rèn)的生成關(guān)系是將我們駝峰命名的實(shí)體進(jìn)行拼接下劃線同時(shí)轉(zhuǎn)小寫(xiě)。 showImg(https://segmentfa...

    weij 評(píng)論0 收藏0
  • Spring/Hibernate 應(yīng)用性能優(yōu)化的7種方法

    摘要:對(duì)于大多數(shù)典型的企業(yè)應(yīng)用而言,其性能表現(xiàn)幾乎完全依賴(lài)于持久層的性能。速成法使用批處理對(duì)于批處理程序,驅(qū)動(dòng)程序提供了旨在減少網(wǎng)絡(luò)來(lái)回傳輸?shù)膬?yōu)化方法。速成法檢查錯(cuò)誤的提交間隔如果你使用批處理程序,提交間隔會(huì)對(duì)性能造成十倍甚至百倍的影響。 對(duì)于大多數(shù)典型的 Spring/Hibernate 企業(yè)應(yīng)用而言,其性能表現(xiàn)幾乎完全依賴(lài)于持久層的性能。此篇文章中將介紹如何確認(rèn)應(yīng)用是否受數(shù)據(jù)庫(kù)約束,同時(shí)...

    lavor 評(píng)論0 收藏0
  • hibernate和jdbc的淵源

    摘要:同時(shí),我們將語(yǔ)句預(yù)編譯在中,這個(gè)類(lèi)可以使用占位符,避免注入,當(dāng)然,后面說(shuō)到的的占位符的原理也是這樣,同時(shí),的占位符原理也是如此。的底層封裝了,比如說(shuō)為了防止注入,一般會(huì)有占位符,也會(huì)有響應(yīng)的占位符。 介紹jdbc 我們學(xué)習(xí)Java數(shù)據(jù)庫(kù)操作時(shí),一般會(huì)設(shè)計(jì)到j(luò)dbc的操作,這是一位程序員最基本的素養(yǎng)。jdbc以其優(yōu)美的代碼和高性能,將瞬時(shí)態(tài)的javabean對(duì)象轉(zhuǎn)化為持久態(tài)的SQL數(shù)據(jù)。...

    includecmath 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<