[Hibernate-JIRA] Created: (HBX-1082) Creating a formula property when reverse engineering
by Anders Reinhardt Hansen (JIRA)
Creating a formula property when reverse engineering
----------------------------------------------------
Key: HBX-1082
URL: http://opensource.atlassian.com/projects/hibernate/browse/HBX-1082
Project: Hibernate Tools
Issue Type: Improvement
Components: reverse-engineer
Affects Versions: 3.2.beta11
Environment: All environments
Reporter: Anders Reinhardt Hansen
Priority: Minor
Having lots of formula properties in mapping files is quite frustrating when reverse engineering database changes.
Therefore it would be a big help if there was a way to write formula properties in the Hibernate Reverse Engineering files.
A property formula is a property of a mapping file which is calculated by hibernate.
I.e.
<class name="XXX">
<column name="xxx" type="xxx" formula="(coloumn1+coloumn2)/coloumn3"/>
</class>
the reveng file could look like this
<hibernate-reverse-engineering>
...
<formula name="xxx" type="xxx" formula="(coloumn1+coloumn2)/coloumn3"/>
</hibernate-reverse-engineering>
Maybe the reverse engineering file is not the correct place for this feature. Suggestions are welcome
--
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
[Hibernate-JIRA] Created: (ANN-824) Annotations - MSSQL, DB2, Sybase - Nullable Foreign PK not allowed
by Gail Badner (JIRA)
Annotations - MSSQL, DB2, Sybase - Nullable Foreign PK not allowed
------------------------------------------------------------------
Key: ANN-824
URL: http://opensource.atlassian.com/projects/hibernate/browse/ANN-824
Project: Hibernate Annotations
Issue Type: Bug
Environment: MSSQL, DB2, Sybase
Reporter: Gail Badner
Assignee: Emmanuel Bernard
Fix For: 3.5
MSSQL, DB2, and Sybase require primary key columns to be non-nullable. Some unit tests are failing using those DBs because a primary keys are defined with one or more nullable columns. This is happening with both trunk and v3_3_1_GA_CP.
I see other JIRA issues that sound related that are marked as fixed, so I'm surprised to see these failing in trunk.
HHH-1935 sounds related. It mentions a bug in SchemaUpdate using @MapKey with @CollectionOfElements.
Workarounds are:
- add "nullable=false" to @JoinColumn
- add "optional=false" to @ManyToOne
- add an @AttributeOverride with @Column(name="mapkey", nullable=false) in case of a @CollectionOfElements using a Map
- add "nullable=false" in @Column when inside a @CollectionId or inside @MapKey
I've included the table DDL causing the failure. Also, there were some tests I couldn't get to pass using a workaround.
org.hibernate.test.annotations.any.AnyTest
create table map_properties ( map_id int not null, property_type varchar(255) null,
property_id int not null, map_key varchar(255) null, primary key (map_id, map_key) )
org.hibernate.test.annotations.cid.CompositeIdTest
create table A ( bid numeric(19,0) null, cid numeric(19,0) null, primary key (bid, cid) )
create table Child ( nth int not null, parentFirstName varchar(255) null, parentLastName varchar(255) null,
primary key (nth, parentFirstName, parentLastName) )
create table TvMagazin ( time datetime null, chan_id int null, presenter_name varchar(255) null,
primary key (chan_id, presenter_name) )
create table TvProgram ( time datetime null, channel_id int null, presenter_name varchar(255) null,
primary key (channel_id, presenter_name) )
create table TvProgramIdClass ( time datetime null, channel_id int null, presenter_name varchar(255) null,
primary key (channel_id, presenter_name) )
org.hibernate.test.annotations.collectionelement.CollectionElementTest
create table Matrix_values ( Matrix_id int not null, element float null, mapkey int null,
primary key (Matrix_id, mapkey) )
create table ScorePerNickName ( BoyId int not null, fld_score int null, mapkey varchar(255) null,
primary key (BoyId, mapkey) )
create table TestCourse_variations ( TestCourse_testCourseId numeric(19,0) not null,
element varchar(255) null, language_code varchar(255) null,
primary key (TestCourse_testCourseId, language_code) )
org.hibernate.test.annotations.collectionelement.indexedCollection.IndexedCollectionOfElementsTest.testIndexedCollectionOfElements
create table contact ( n_key_person int not null, name varchar(255) null, n_key_contact numeric(19,0) null,
primary key (n_key_contact) )
org.hibernate.test.annotations.identifiercollection.IdentifierCollectionTest.testIdBag
NOTE: I could not find a workaround to fix this test.
create table PASSPORT_STAMP ( Passport_passport_id numeric(19,0) not null,
stamps_id numeric(19,0) not null, COLLECTION_ID numeric(19,0) null,
primary key (COLLECTION_ID) )
create table PASSPORT_VISASTAMP ( Passport_passport_id numeric(19,0) not null,
visaStamp_id numeric(19,0) not null, COLLECTION_ID numeric(19,0) null,
primary key (COLLECTION_ID) )
org.hibernate.test.annotations.indexcoll.IndexedCollectionTest
create table Atmosphere_Gas ( Atmosphere_id int not null, gases_id int not null,
gas_name varchar(255) null, primary key (Atmosphere_id, gas_name) )
org.hibernate.test.annotations.target.TargetTest
NOTE: I could not find a workaround to fix this test.
create table Brand_LuggageImpl ( Brand_id numeric(19,0) not null,
luggagesBySize_id numeric(19,0) not null, name varchar(255) null,
primary key (Brand_id, name) )
--
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
[Hibernate-JIRA] Created: (HV-164) Add test for default group sequence isolation
by Emmanuel Bernard (JIRA)
Add test for default group sequence isolation
---------------------------------------------
Key: HV-164
URL: http://opensource.atlassian.com/projects/hibernate/browse/HV-164
Project: Hibernate Validator
Issue Type: Bug
Components: engine
Affects Versions: 4.0.0.Beta1
Reporter: Emmanuel Bernard
Assignee: Hardy Ferentschik
Fix For: 4.0.0.Beta2
public interface Minimal {}
public interface Heavy {}
## test 1 - Rule D
@GroupSequence( {Minimal.class, A.class} )
public class A {
@Max(value = 10, groups = Minimal.class) int size;
@Size(max=50) String name; //A group
}
@GroupSequence( {B.class, Heavy.class} )
public class B extends A {
@SafeEncryption(groups = Heavy.class) String encryptionKey;
@Size(max=50) String nickname; //B group
}
when validating Default.class on B, you need to validate sequentially:
- @Size on name and @Size on nickname (A is part of B)
- @SafeEncryption on encryptionKey
note that @Max on size is not validated as it's not part of the sequence nor the group A
## test 2 - Rule D
@GroupSequence( {Minimal.class, A.class} )
public class A {
@Max(value = 10, groups = Minimal.class) int size;
@Size(max=50) String name; //A group
}
@GroupSequence( {Minimal.class, B.class, Heavy.class} )
public class B extends A {
@SafeEncryption(groups = Heavy.class) String encryptionKey;
@Size(max=50) String nickname; //B group
}
when validating Default.class on B, you need to validate sequentially:
- @Max on size (Minnimal group)
- @Size on name and @Size on nickname (A is part of B)
- @SafeEncryption on encryptionKey
## test 3 Rules C1 and C2
@GroupSequence( {Minimal.class, A.class} )
public class A {
@Max(value = 10, groups = Minimal.class) int size;
@Size(max=50) String name; //A group
}
public class B extends A {
@SafeEncryption(groups = Heavy.class) String encryptionKey;
@Size(max=50) String nickname; //B group
}
when validating Default.class on B, you need to validate sequentially:
- @Max on size (Minimal)
- @Size on name (A)
and in // at any time @Size on nickname (B group). Note that B is not constrained by the group sequence defined by A, B contains A. @Size on nickname could fail but @Size on name will be validated. Likewise @Max on size could fail and @Size on nickname (A) will be validated (note that @Size on nickname (B) will not as it has to be validated only if Minimal constraints pass)
All based on http://people.redhat.com/~ebernard/validation/#constraintdeclarationvalid...
particularly
C1, C2 and D
--
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
[Hibernate-JIRA] Created: (HV-138) JPAValidateListener checks @NotNull fields that are filled after the @PrePersist call
by Julien Kronegg (JIRA)
JPAValidateListener checks @NotNull fields that are filled after the @PrePersist call
-------------------------------------------------------------------------------------
Key: HV-138
URL: http://opensource.atlassian.com/projects/hibernate/browse/HV-138
Project: Hibernate Validator
Issue Type: Bug
Affects Versions: 3.1.0.GA
Environment: Hibernate 3.3.1.GA, Hibernate annotations 3.4.0.GA, Hibernate entity manager 3.4.0.GA, POJO annotated entities, DB2
Reporter: Julien Kronegg
According to Hibernate validation documentation ( http://www.hibernate.org/hib_docs/validator/reference/en/html_single/#val... ) we can annotate an entity with @EntityListeners({JPAValidateListener.class}) to validate the fields using the @PrePersist / @PreUpdate JPA events handlers.
I tryied with the following entity:
@Entity
@Table(...)
@EntityListeners({JPAValidateListener.class})
public class A {
private int id;
private String text;
@Id
@Column(...)
@NotNull
@GeneratedValue(...)
@GenericGenerator(...)
public int getId() { return id; }
public void setId(int id) { this.id=id; }
...
}
Problem is that the @PrePersist event is raised before some fields are automatically filled (e.g. @Id annotated). So the JPAValidateListener raises an exception saying that the identifier cannot be null.
The exception root cause detail is (InvalidState: id cannot be null) and the stacktrace is:
org.hibernate.validator.InvalidStateException: validation failed for : my.package.A
at org.hibernate.validator.ClassValidator.assertValid(ClassValidator.java:666)
at org.hibernate.validator.event.JPAValidateListener.onChange(JPAValidateListener.java:62)
...// some reflection StacktraceElement
at org.hibernate.ejb.event.ListenerCallback.invoke(ListenerCallback.java:31)
at org.hibernate.ejb.event.EntityCallbackHandler.callback(EntityCallbackHandler.java:80)
at org.hibernate.ejb.event.EntityCallbackHandler.preCreate(EntityCallbackHandler.java:49)
at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:48)
at org.hibernate.event.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:154)
at org.hibernate.event.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:110)
at org.hibernate.event.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:61)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:645)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:619)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:623)
...
The EJB3PersistEventListener.saveWithGeneratedId() method looks like:
protected Serializable saveWithGeneratedId(...) {
callbackHandler.preCreate(entity); // raises the @PrePersist JPA event
return super.saveWithGeneratedId(...); // sets the identifier
}
Thus, the JPAValidateListener validates the whole Entity and does not take the entity lifecycle into account. The JPAValidateListener should check all fields except the ones which are known to be modified/setled after the call to the validator.
This may also be the case for other generated fields such as the ones annotated with @Version (I did not check 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
[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