Javassist dependency conflict in the ORM modules for WildFly
by Sanne Grinovero
Hi all,
there's a conflict in the Javassist versions of the WildFly modules of
Hibernate ORM 5.2.4.Final, but I'm not sure how to proceed as I'm not
familiar with this functionality.
The module declares *both*:
- a dependency to the WildFly provided Javassist: <module
name="org.javassist"/>
- inclusion of Hibernate's own version of Javassist: <resource-root
path="javassist-3.20.0-GA.jar"/>
Having both is causing trouble as they are both visible to the
Hibernate classloader; however I couldn't score a quick win with the
testsuiste by disabling either (all tests using these modules in the
Hibernate Search testsuite fail).
I suspect the problem is that JipiJapa also depends on the <module
name="org.javassist"/>, while ORM obviously needs the more recent
version of it.
I'm not familiar with what JipiJapa's business around Javassist; could
we keep the two clearly separated?
Especially if we want to make Byte Buddy a viable alternative, I
suspect the solution is that JipiJapa should not depend on Javassist
directly, but invoke a generic instrumentation SPI on Hibernate; also
with JipiJapa not able to see Javassist at all, we'd be in control of
the one and only Javassist version visible to ORM: the one we compile
and test with.
Thanks,
Sanne
7 years, 7 months
HHH-11144
by Gail Badner
HHH-11144 involves an entity that has 2 one-to-many associations with the
same type of entity, and both associations have orphanRemoval = true.
Andrea created a PR with test case at [1]
I am not sure if this is a valid mapping. I I would like your thoughts on
this.
Here is an excerpt of the relevant bits:
@Entity(name = "Item")
public static class Item {
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval
= true)
protected Set<ItemRelation> lowerItemRelations = new LinkedHashSet<>();
@OneToMany(mappedBy = "child", cascade = CascadeType.ALL, orphanRemoval =
true)
protected Set<ItemRelation> higherItemRelations = new LinkedHashSet<>();
}
@Entity(name = "ItemRelation")
public static class ItemRelation {
@ManyToOne(optional = false)
@JoinColumn(name = "PARENT_ID")
private Item parent;
@ManyToOne(optional = false)
@JoinColumn(name = "CHILD_ID")
private Item child;
}
HHH-11144 describes inconsistent behavior observed when
Item#lowerItemRelations and Item#higherItemRelations both contain the same
ItemRelation, then one of the collections is cleared.
If the non-cleared collection is uninitialized, then the ItemRelation is
orphan deleted.
If the non-cleared collection is initialized, then the orphan-deleted
ItemRelation is rescued when PERSIST_ON_FLUSH cascades to the non-cleared
collection elements. The next time the collections are loaded from the
database, both will still contain that same ItemRelation.
The spec says:
"Portable applications must otherwise not depend upon a specific order of
removal, and must not reassign an entity that has been orphaned to another
relationship or *otherwise attempt to persist it*"
Is Hibernate doing the right thing by rescuing an orphan-deleted entity?
In addition, this mapping allows a particular EntityRelation to be
associated with 2 different Item entities, which would mean that the same
ItemRelation would have 2 different owners with respect to orphan deletion..
The spec says:
"The orphanRemoval functionality is intended for entities that are privately
“owned” by their parent entity."
Does this mean that the mapping is invalid, since it would allow multiple
parent entities, or does it mean that the resulting behavior is undefined
(thus non-portable)?
Please let me know your thoughts.
Thanks,
Gail
[1] https://github.com/hibernate/hibernate-orm/pull/1607
7 years, 8 months
dynamic instantiation queries
by Steve Ebersole
Historically (well before JPA) HIbernate would handle dynamic instantiation
queries in cases where one of the arguments being an entity-reference by
passing just the entity's identifier rather than a complete reference to
the entity. To be clear, I am talking about a query like:
select new DTO( p ) from Person p
Hibernate implicitly treats this like:
select new DTO( p.id ) from Person p
and expects DTO to have a ctor taking the appropriate ID type.
JPA came along and also defines support for dynamic instantiation queries,
but does not specify one way or the other how this case should be handled.
I have been told other providers interpret this the opposite way. Makes
sense. I think it is time we at least allow that as an option. Or maybe a
nicer implementation that looks for both and picks the available one (if
that's not too much effort).
What do y'all think?
7 years, 9 months
6.0 - ResultTransformer
by Steve Ebersole
Another legacy concept I'd like to revisit as we move to 6.0 is the
Hibernate ResultTransformer. I'd argue that ResultTransformer is no longer
needed, especially in it's current form.
Specifically, ResultTransformer defines 2 distinct ways to transform the
results of a query:
1. `#transformTuple` - this method operates on each "row" of the result,
allowing the user to transform the Object[] into some other structure.
This is specifically the one I see no value in moving forward. Between
dynamic-instantiation, Tuple-handling, etc I think users have the needed
capabilities to transform the query result tuples.
2. `#transformList` - this one operates on the query result as a whole
(unless scroll/iterate are used). This method at least adds something that
cannot be done in another way. But I'd still personally question its
overall usefulness.
Does anyone have an argument for continuing to support either of these?
Personally, I propose just dropping the ResultTransformer support
altogether.
7 years, 9 months
HHH-11155 : problems updating lazy properties in lazy groups
by Gail Badner
Static update strings appear to cover only the following situations:
1) there are no uninitialized properties (so all updateable attributes
should be updated);
2) all lazy properties are uninitialized (so only
non-lazy, updateable attributes should be updated).
As of 5.1, we have "lazy groups". It is possible some lazy groups are
initialized, and some are uninitialized. We have a couple of alternatives
for dealing with the various combinations:
For example, if there are are 3 lazy groups: lazyGroup1, lazyGroup2,
lazyGroup3.
1) Generate SQL update strings for all possible combinations of initialized
lazy groups:
SQL update strings are already generated for the following combinations:
* lazyGroup1: uninitialized; lazyGroup2: uninitialized; lazyGroup3:
uninitialized
* lazyGroup1: initialized; lazyGroup2: initialized; lazyGroup3:
initialized
SQL update strings for the following combinations need to be generated to
fix the bug:
* lazyGroup1: initialized; lazyGroup2: uninitialized; lazyGroup3:
uninitialized
* lazyGroup1: uninitialized; lazyGroup2: initialized; lazyGroup3:
uninitialized
* lazyGroup1: uninitialized; lazyGroup2: uninitialized; lazyGroup3:
initialized
* lazyGroup1: initialized; lazyGroup2: initialized; lazyGroup3:
uninitialized
* lazyGroup1: initialized; lazyGroup2: uninitialized; lazyGroup3:
initialized
* lazyGroup1: uninitialized; lazyGroup2: initialized; lazyGroup3:
initialized
The update strings could be stored in a Map with key containing the names
(or indexes?) of the corresponding initialized lazy groups.
2) Generate dynamic update strings when there is at least 1 uninitialized
group, or when there are more than N lazy groups. What should N be?
Comments or suggestions?
A related bug is that calling a setter on a lazy property only initializes
that one lazy property. It should also initialize other properties in the
same lazy group. This one is pretty easy to fix.
Thanks,
Gail
8 years
Feature reduction in Hibernate Search
by Sanne Grinovero
We're not working yet on Hibernate Search 6, but since it's the next
big chapter I hope we're all making notes - if not JIRAs - of what
we'd like changed in the next version.
As a reminder, the main themes of version 6 are:
- upgrade to Apache Lucene 6
- API changes to (better) accommodate for non-Lucene backends, such
as Elasticsearch
- align with the Hibernate portfolio of projects version 6
I'd like you to also think about features which should be dropped:
it's not healthy - certainly not sustainable - to see a project like this
as a place to keep adding features, without ever removing or
simplifying some.
If you have thoughts in the area, let's bring them up in the mailing
list: no rush, but the sooner the better.
However I'd prefer to discuss each proposal independently so please
refrain from sending specific deprecation ideas to this same email
thread.
Thanks,
Sanne
8 years
6.0 - Type redesign
by Jordan Gigov
I've been reading the wiki and email archives, and I have some notes
for what needs to be decided before it needs to become retrofitted.
After all, all that retrofitting is what the reason the types need to
be redesigned.
LiteralType.objectToSQLString is only used to append the DiscriminatorValue.
Can't it just work with regular binding to the PreparedStatement so
the unsafe interface can be removed?
A type should be able to define classes Interfaces and Abstract
classes that it can handle in their Java types.
This will enable implementing handlers for things like javax.script.*
objects that can have different providers, thus different class names
of the final object.
That would have to be a secondary check if no match is found by Java
class name, because it's slower and dangerous when binding
parameters to a query.
If stored as Class object references, they would have to be held in
WeakReference objects tied to a ReferenceQueue, so as not to
prevent garbage collection when a context is unloaded in a multi-context server.
If stored as Strings, there would have to be a call to Class.forName
for each, which if successful would have to check isInstance on the
object or isAssignableFrom on it's class (when evaluating DB model).
There are currently no notes on how to handle binding the values to a
PreparedStatement/CallableStatement.
There is also no mention of how java.sql.SQLType that was added in
Java 8 comes into play, which will help with vendor-specific types.
When converting the new types to a bindable object they will need
access to the Dialect and these methods of the java.sql.Connection:
createArrayOf
createBlob
createClob
createNClob
createSQLXML
createStruct
getClientInfo
getMetaData which returns DatabaseMetaData which can give access to
the java.sql.Connection if we're trying to abstract away from it.
Maybe also to:
setClientInfo
getWarnings when reading results from the database
getTypeMap
setTypeMap
On Thu Jul 21 15:27:49 EDT 2016 Steve Ebersole <steve at hibernate.org> wrote:
> I know we could get around this by splitting (or keeping split) the notions
> of ORM Type and JPA Type, but I would like to avoid that : this unification
> is going to be important to the SQM Criteria support.
Reading the description of javax.persistence.metamodel.Type, I'm not
sure it serves the same purpose as Hibernate's Type and that it should
be a super-interface of it.
In fact, starting to read the Metamodel API chapter where these
interfaces are defined, I'm fairly certain it's supposed to reflect
the structure of the persistence unit.
In other words, I don't think javax.persistence.metamodel.Type fits
anywhere in this picture and it's a different concept altogether.
As for OGM (which I've never used, but here's an idea) the problem
with SqlTypeDescriptor (discussed in end of June, as I read the mail
archives)
maybe could be turned into an extension of a more generic
StorageTypeDescriptor, and SQL would be just one type of storage? I
don't know
how that would work, since I've never had to use NoSQL and don't even
know if that makes sense.
Maybe the persistence context should provide the binders/extractors to
each type upon use.
8 years