[Hibernate-JIRA] Created: (EJB-313) delete twice triggers detached entity error, but change to composite primary key and the exception is gone.
by Simon Ng (JIRA)
delete twice triggers detached entity error, but change to composite primary key and the exception is gone.
-----------------------------------------------------------------------------------------------------------
Key: EJB-313
URL: http://opensource.atlassian.com/projects/hibernate/browse/EJB-313
Project: Hibernate Entity Manager
Issue Type: Bug
Affects Versions: 3.2.0.cr3
Environment: Windows XP Professional + Postgres 8.1 + Spring 2 + JPA + Hibernate 3.2.3
Reporter: Simon Ng
Attachments: DeleteTwice.zip
The attached file DeleteTwice.zip has the entire project; and the primary key is a composite primary key. Run the unit test and there is no exception, just an INFO level message of "handling transient entity in delete processing".
Next, delete RestaurantPK.java, and change Restaurant.java to use a simple primary key:
package blog.jpa.domain;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
@Entity
public class Restaurant {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Change the onSetUpInTransaction to use different SQL statement to reflect a different table
protected void onSetUpInTransaction() throws Exception {
jdbcTemplate.execute("insert into restaurant (id, name) values (1, 'Burger Barn')");
jdbcTemplate.execute("insert into restaurant (id, name) values (2, 'Veggie Village')");
jdbcTemplate.execute("insert into restaurant (id, name) values (3, 'Dover Diner')");
}
drop the table restaurant and run the unit test again. Now there is an exception
[junit] Testcase: testDeleteRestaurant(blog.jpa.dao.JpaRestaurantDaoTests): Caused an ERROR
[junit] Removing a detached instance blog.jpa.domain.Restaurant#3; nested exception is java.lang.IllegalArgumentExce
ption: Removing a detached instance blog.jpa.domain.Restaurant#3
[junit] org.springframework.dao.InvalidDataAccessApiUsageException: Removing a detached instance blog.jpa.domain.Res
taurant#3; nested exception is java.lang.IllegalArgumentException: Removing a detached instance blog.jpa.domain.Restaura
nt#3
[junit] Caused by: java.lang.IllegalArgumentException: Removing a detached instance blog.jpa.domain.Restaurant#3
[junit] at org.hibernate.ejb.event.EJB3DeleteEventListener.performDetachedEntityDeletionCheck(EJB3DeleteEventLis
tener.java:45)
The java.lang.IllegalArgumentException is specified in the JPA spec.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
15 years, 6 months
[Hibernate-JIRA] Created: (HHH-2401) CLOB truncation on DB2 when using 2 or 3 byte chars (UTF8)
by Simon Jongsma (JIRA)
CLOB truncation on DB2 when using 2 or 3 byte chars (UTF8)
----------------------------------------------------------
Key: HHH-2401
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2401
Project: Hibernate3
Type: Bug
Components: core
Versions: 3.2.0.ga
Environment: Hibernate 3.2.0 GA + JBoss 4.0.4.GA on Windows XP + DB2 UDB for ISeries V5R3 + IBM JT Open driver 4.9
Reporter: Simon Jongsma
Priority: Minor
Attachments: ClobTruncated.zip
A CLOB column is used in DB2 mapped to a String in Java with the Hibernate "Text" mapping.
The column in DB2 has a CCSID 1208 which means "UTF8" (= Unicode).
The CLOB truncation occurs when characters are used that are UTF8 coded in more than one byte.
In that the string is truncated when persisted in the database.
For example the string
"Granpré Molière†; 0123456789". This string has three diacritical marks in it.
The é and è are coded in two bytes in UTF8 and the † in three bytes.
This string will be stored as "Granpré Molière†; 012345".
So "6789" is not stored.
It appears as though Hibernate does not take into account that a character can be more than 1 byte in UTF8.
The number of missing char's at the end is exactly: string.getBytes("UTF-8").length minus string.length()
It is not a problem of DB2 or the JT Open driver:
Storing and retrieving (from a Java program) the same String directly via Jdbc into the DB2 table and retrieving it, works 100% fine.
So this clearly points to a problem somewhere in Hibernate.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
15 years, 6 months
[Hibernate-JIRA] Créée: (HHH-2086) Patch for bug HHH-2076 and to be able to use <formula> in <key> for <one-to-many>
by Xavier Brénuchon (JIRA)
Patch for bug HHH-2076 and to be able to use <formula> in <key> for <one-to-many>
---------------------------------------------------------------------------------
Key: HHH-2086
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2086
Project: Hibernate3
Type: Patch
Components: core
Versions: 3.2.0.cr4
Reporter: Xavier Brénuchon
Attachments: formula_one_to_many.patch
Hello,
There is a patch to correct bug HHH-2076 and make an improvement for HHH-944.
In fact, theses 2 cases are linked. They need, amongst other things, a formula in the right part of outer join.
This patch is simple but many class concerns (to propagate formula templates).
About formula in one-to-many :
You must have at least a column (not only formula), because it's not possible to have an Update order without at least a column. If it is the case, hibernate patch will raise an MappingException rightly.
This patch add two TestCase :
org.hibernate.test.onetoone.bidirectionnalformula. OneToOneBidirectionalFormulaTest
org.hibernate.test.onetomany.formula. OneToManyFormulaTest
Would it be possible to integrate this patch into Hibernate 3.2 ?
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
15 years, 6 months
[Hibernate-JIRA] Created: (HBX-812) Fetching Children of Database _crawls_.
by Syd Poetry (JIRA)
Fetching Children of Database _crawls_.
---------------------------------------
Key: HBX-812
URL: http://opensource.atlassian.com/projects/hibernate/browse/HBX-812
Project: Hibernate Tools
Type: Bug
Components: reverse-engineer
Versions: 3.2beta8
Environment: MySQL 5.0, Eclipse 3.2, JDK 1.5, Beta8 for Hibernate Tools
Reporter: Syd Poetry
I just updated a bunch of components for Eclipse (mostly related to Visual Editor); added a couple of tables to my database, went to regenerate all the POJO clases .hbm.xml mapping files, and found that anything that queries the database schema runs abysmally slow.
Updated the tools from beta6 to beta8 thinking it might be a conflict with one of the updates that was performed, still very slow (5+ minutes to retrieve a list of tables!). Deleted all my hibernate-related XML files thinking it might be a parsing error, went to generate a new console file, and revenge.xml, found out that any listbox that tried to access the schema appeared to be hanging. It finishes after much hard-drive crunching. I have 2.2 GBs free running windows XP, MEM usage is 856 MB out of 1.5 GB physical memory. Just out of curiousity, is *anyone* else having this slow response for schema detection? I'm wondering if I have to update another component like a driver or something like that.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
15 years, 7 months
[Hibernate-JIRA] Created: (HHH-3362) NullPointerException in org.hibernate.dialect.Dialect$2.getReturnType
by Istvan Kovacs (JIRA)
NullPointerException in org.hibernate.dialect.Dialect$2.getReturnType
---------------------------------------------------------------------
Key: HHH-3362
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3362
Project: Hibernate3
Issue Type: Bug
Components: core
Affects Versions: 3.2.6
Environment: Hibernate Core 3.6.2 GA, hsqldb
Reporter: Istvan Kovacs
Attachments: bug_src.zip
java.lang.NullPointerException
at org.hibernate.dialect.Dialect$2.getReturnType(Dialect.java:85)
at org.hibernate.hql.ast.util.SessionFactoryHelper.findFunctionReturnType(SessionFactoryHelper.java:382)
at org.hibernate.hql.ast.tree.AggregateNode.getDataType(AggregateNode.java:21)
at org.hibernate.hql.ast.tree.SelectClause.initializeExplicitSelectClause(SelectClause.java:143)
at org.hibernate.hql.ast.HqlSqlWalker.useSelectClause(HqlSqlWalker.java:705)
at org.hibernate.hql.ast.HqlSqlWalker.processQuery(HqlSqlWalker.java:529)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:645)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:281)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:229)
at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:228)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:160)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:111)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:56)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:72)
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:133)
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:112)
at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1623)
at org.hibernate.console.HQLQueryPage.setSession(HQLQueryPage.java:106)
at org.hibernate.console.ConsoleConfiguration$4.execute(ConsoleConfiguration.java:388)
at org.hibernate.console.execution.DefaultExecutionContext.execute(DefaultExecutionContext.java:65)
at org.hibernate.console.ConsoleConfiguration.executeHQLQuery(ConsoleConfiguration.java:383)
[...]
3 classes:
Employee: Long ID; String name; Shop shop
Shop: Long ID; String name; Set<Employee> employees; Map<Product, Integer> stock
Product: Long ID; String name
I mapped them to RDBMS using Hibernate. There's a table to hold stock info:
SHOP_PRODUCT_STOCK - has fields SHOP_ID, PRODUCT_ID, AMOUNT
SQL to query the average stock of each product:
select p.name as name, avg(sps.amount) as avg_stock
from Shop s, Shop_Product_Stock sps, Product p
where sps.product_id=p.product_id and sps.product_id=p.product_id
group by p.name
order by p.name;
Attempt in HQL that the produces exception:
select p, avg(s.stock[p])
from Shop s, Product p
group by p
I've also tried SELECTing and GROUPing BY p.id and p.name. None of the three variants work.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
15 years, 7 months
[Hibernate-JIRA] Created: (HHH-2983) Properties of a Map key not consistently populated before being put into the Map
by Dobes Vandermeer (JIRA)
Properties of a Map key not consistently populated before being put into the Map
--------------------------------------------------------------------------------
Key: HHH-2983
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2983
Project: Hibernate3
Issue Type: Bug
Components: core
Affects Versions: 3.2.5
Environment: Glassfish v2 b58, PostgreSQL 8.2, running in Windows XP
Reporter: Dobes Vandermeer
I'm getting weird behavior where my map correctly has two entries when fetched as part of a list, and only one entry when I fetch it using EntityManager.get().
Here's an abbreviated version of the mapping for the class that contains the Map:
@Entity(name="Account")
public class Account implements Comparable<Account>, SecurityChecks {
private Long id;
private Map<Currency, Balance> balances = new HashMap<Currency, Balance>(); // Current balance in each currency
public Account() {
}
@Id @GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@OneToMany(cascade={CascadeType.ALL}, mappedBy="account")
@MapKey(name="currency")
public Map<Currency, Balance> getBalances() {
return balances;
}
public void setBalances(Map<Currency, Balance> balances) {
this.balances = balances;
}
}
And the class that it contains:
@Entity(name="Balance")
@Table(uniqueConstraints={@UniqueConstraint(columnNames={ "account_id", "currency_id" })})
public class Balance implements SecurityChecks {
private Long id;
private Account account;
private Currency currency;
private long amount;
@ManyToOne(cascade=CascadeType.PERSIST, optional=false)
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
@Column(nullable=false)
public long getAmount() {
return amount;
}
public void setAmount(long amount) {
this.amount = amount;
}
@ManyToOne(cascade=CascadeType.PERSIST, optional=false)
@JoinColumn(name="currency_id")
public Currency getCurrency() {
return currency;
}
public void setCurrency(Currency currency) {
this.currency = currency;
}
@Id @GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
And a class that has a list of Accounts:
@Entity(name="Business")
public class Business implements SecurityChecks {
private Long id;
private String name;
private List<Account> accounts = new ArrayList<Account>();
@Id @GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@OneToMany(mappedBy="business", cascade={CascadeType.ALL})
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
@Column(nullable=false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Here's the definition of Currency:
package com.habitsoft.books.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Transient;
import com.habitsoft.books.service.client.CurrencyFormatter;
@Entity(name="Currency")
public class Currency implements Comparable<Currency> {
private Long id;
private String currencyCode;
private String name;
private String prefix = "";
private String suffix = "";
private int decimalPlaces;
@Id
@GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result + ((getCurrencyCode() == null) ? 0 : getCurrencyCode().hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Currency other = (Currency) obj;
if (getCurrencyCode() == null) {
if (other.getCurrencyCode() != null)
return false;
} else if (!getCurrencyCode().equals(other.getCurrencyCode()))
return false;
return true;
}
public int compareTo(Currency obj) {
if (this == obj)
return 0;
if (obj == null)
return -1;
final Currency other = (Currency) obj;
return getCurrencyCode().compareTo(other.getCurrencyCode());
}
public String getCurrencyCode() {
return currencyCode;
}
public void setCurrencyCode(String currencyCode) {
this.currencyCode = currencyCode;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Here's a line of code I use to fetch the Account directly:
return em.find(Account.class, accountId);
Here's how I fetch the list of accounts for a business:
Business business = em.find(Business.class, businessId);
return business.getAccounts().subList(offset, offset+limit);
What is very, very odd to me is that the Accounts returned by the first form have just a single Balance instance in the map, when there should be two, whereas the ones returned by the second form have both entries I'm expecting.
Hibernate prints the following SQL queries:
Hibernate: select account0_.id as id270_0_, account0_.business_id as business5_270_0_, account0_.description as descript2_270_0_, account0_.name as name270_0_, account0_.type as type270_0_ from Account account0_ where account0_.id=?
Hibernate: select balances0_.account_id as account3_2_, balances0_.id as id2_, balances0_.currency_id as formula5_2_, balances0_.id as id271_1_, balances0_.account_id as account3_271_1_, balances0_.amount as amount271_1_, balances0_.currency_id as currency4_271_1_, currency1_.id as id275_0_, currency1_.currencyCode as currency2_275_0_, currency1_.decimalPlaces as decimalP3_275_0_, currency1_.name as name275_0_, currency1_.prefix as prefix275_0_, currency1_.suffix as suffix275_0_ from Balance balances0_ inner join Currency currency1_ on balances0_.currency_id=currency1_.id where balances0_.account_id=?
If I execute these queries against the database manually, the correct number of results is returned, so it seems likely that hibernate is generating the correct query, but then populating the map incorrectly.
I took a guess that hashCode() and equals() in Currency were the most likely cause of the issue and indeed if I change them to use id instead of currencyCode the problem goes away.
So, for some odd reason hibernate is populating the id field and not the other fields, and then putting it into the Map, but only when the object is fetched directly. This seems to point to some inconsistency in the way hibernate is initializing the objects and maps, somewhere.
The workaround is to not use any fields except id in hashCode() and equals() for an entity used as a map key, and to ensure you call persist() on the key objects before putting them into the map. This seems like a reasonable constraint to me, but it would be nice if the behavior was more consistent to avoid excessive head-scratching.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
15 years, 7 months