[JIRA] (HHH-13940) Hibernate session does not save subclass information correctly when using batch size >0 and hibernate.discriminator.ignore_explicit_for_joined
by Willem Borgesius (JIRA)
Willem Borgesius ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... ) *created* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiYzNiMzY4M2U4... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-13940?atlOrigin=eyJpIjoiYzNiMz... ) HHH-13940 ( https://hibernate.atlassian.net/browse/HHH-13940?atlOrigin=eyJpIjoiYzNiMz... ) Hibernate session does not save subclass information correctly when using batch size >0 and hibernate.discriminator.ignore_explicit_for_joined ( https://hibernate.atlassian.net/browse/HHH-13940?atlOrigin=eyJpIjoiYzNiMz... )
Issue Type: Bug Affects Versions: 5.2.15, 5.2.16, 5.2.17, 5.2.18, 5.4.0, 5.4.9, 5.3.16 Assignee: Unassigned Attachments: hibernate-orm-5-ignore-explicit.zip Components: hibernate-core Created: 08/Apr/2020 04:52 AM Priority: Major Reporter: Willem Borgesius ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... )
We have a use case to set the flag hibernate.discriminator.ignore_explicit_for_joined to true. Unfortunately we have code we can't change that uses inconsistent DiscriminatorValue's.
It seems that when hibernate.jdbc.batch_size is > 0 and hibernate.discriminator.ignore_explicit_for_joined is true, the data for the a subclass of InheritanceType.JOINED does not get saved.
I tried upgrading to 5.3.16.Final due to the fix of HHH-12968 ( https://hibernate.atlassian.net/browse/HHH-12968 ) Closed , but it did not solve my problem.
Our codebase uses hibernate 5.2.18.Final, but i created a unit test within our application to test over hibernate versions. It works as expected with hibernate 5.2.14.Final, and seems to be fixed in 5.4.10.Final.
I added a testcase derived from the template, trying to isolate the problem as much as possible.
The testcase passes with hibernate 5.4.10.Final and fails with versions between 5.2.18.Final and 5.4.10.Final.
The testcase also passes if either hibernate.discriminator.ignore_explicit_for_joined is set to false or hibernate.jdbc.batch_size is set to 0.
Due to the fact we use some external code we unfortunately can't upgrade to hibernate 5.3. In our osgi module there is a bundle dependency on org.hibernate.core bundle and this seems to have been moved to org.hibernate.orm.core).
( https://hibernate.atlassian.net/browse/HHH-13940#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-13940#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100124- sha1:c13ca0d )
4 years, 6 months
[JIRA] (HHH-13939) H2Dialect @GeneratedValue regression on schema generation, uses sequence instead of generated by default as identity
by IT Support (JIRA)
IT Support ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... ) *updated* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiN2E3MDE1OWE4... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-13939?atlOrigin=eyJpIjoiN2E3MD... ) HHH-13939 ( https://hibernate.atlassian.net/browse/HHH-13939?atlOrigin=eyJpIjoiN2E3MD... ) H2Dialect @GeneratedValue regression on schema generation, uses sequence instead of generated by default as identity ( https://hibernate.atlassian.net/browse/HHH-13939?atlOrigin=eyJpIjoiN2E3MD... )
Change By: IT Support ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... )
In Hibernate 4.x, specifically 4.3.11 , all worked as expected.
{code:xml|title= * persistence.xml snippet } *
{code:xml} <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:unittests" />
{code}
{code:sql|title= * 4.x generated SQL } *
Hibernate
{code : sql} create table dbo.office (officeid bigint generated by default as identity, office varchar(255) not null, description varchar(255), sequence varchar(255), orgid bigint not null, primary key (officeid))
{code}
{code:sql|title=
In 5.x the DB structure has changed in incompatible ways.
*5.x generated SQL } *
{code:sql} create table dbo.office (officeid bigint not null, office varchar(255) not null, description varchar(255), sequence varchar(255), orgid bigint not null, primary key (officeid))
create sequence hibernate_sequence start with 1 increment by 1
{code}
I have confirmed the dialect values are sensible. The error seems to be inside / around the {{ SessionFactoryImpl }} 's {{ identifierGenerators }} . While the dialect indicates Identity generation, the generator seems to be a result of {{ DefaultIdentifierGeneratorFactory }} , which produces sequence based ids.
Specifically the {{ metadata.getEntityBindings() }} returns a {{ PersistentClass }} model where the identifier is a {{ SimpleValue }} whose {{ identifierGenerator }} is a {{ SequenceStyleGenerator }} .
This can be backtracked to:
*EntityManagerFactoryBuilderImpl*
{code:java |title=EntityManagerFactoryBuilderImpl }
private MetadataImplementor metadata() {
if ( this.metadata == null ) {
this.metadata = MetadataBuildingProcess.complete( managedResources, metamodelBuilder.getMetadataBuildingOptions() );
}
return metadata;
}
{code}
This is not related to:
* [ HHH-13727 ]
* [ HHH-13597 ]
( https://hibernate.atlassian.net/browse/HHH-13939#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-13939#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100124- sha1:c13ca0d )
4 years, 6 months
[JIRA] (HHH-13939) H2Dialect @GeneratedValue regression on schema generation, uses sequence instead of generated by default as identity
by IT Support (JIRA)
IT Support ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... ) *created* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiZjBhNDFmYjNm... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-13939?atlOrigin=eyJpIjoiZjBhND... ) HHH-13939 ( https://hibernate.atlassian.net/browse/HHH-13939?atlOrigin=eyJpIjoiZjBhND... ) H2Dialect @GeneratedValue regression on schema generation, uses sequence instead of generated by default as identity ( https://hibernate.atlassian.net/browse/HHH-13939?atlOrigin=eyJpIjoiZjBhND... )
Issue Type: Bug Affects Versions: 5.0.0.Final, 5.4.13 Assignee: IT Support ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... ) Components: hibernate-jpamodelgen Created: 07/Apr/2020 13:40 PM Environment: Java 7, Java 8, h2-1.4.200.jar Labels: documentation regression Priority: Major Reporter: IT Support ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... )
In Hibernate 4.x, specifically 4.3.11
*persistence.xml snippet*
<property name= "hibernate.dialect" value= "org.hibernate.dialect.H2Dialect" />
<property name= "hibernate.hbm2ddl.auto" value= "create-drop" />
<property name= "javax.persistence.jdbc.url" value= "jdbc:h2:mem:unittests" />
*4.x generated SQL*
Hibernate: create table dbo.office (officeid bigint generated by default as identity , office varchar (255) not null , description varchar (255), sequence varchar (255), orgid bigint not null , primary key (officeid))
*5.x generated SQL*
create table dbo.office (officeid bigint not null , office varchar (255) not null , description varchar (255), sequence varchar (255), orgid bigint not null , primary key (officeid))
create sequence hibernate_sequence start with 1 increment by 1
I have confirmed the dialect values are sensible. The error seems to be inside / around the SessionFactoryImpl's identifierGenerators. While the dialect indicates Identity generation, the generator seems to be a result of DefaultIdentifierGeneratorFactory, which produces sequence based ids.
Specifically the metadata.getEntityBindings() returns a PersistentClass model where the identifier is a SimpleValue whose identifierGenerator is a SequenceStyleGenerator
This can be backtracked to:
*EntityManagerFactoryBuilderImpl*
private MetadataImplementor metadata() {
if ( this.metadata == null ) {
this.metadata = MetadataBuildingProcess.complete( managedResources, metamodelBuilder.getMetadataBuildingOptions() );
}
return metadata;
}
This is not related to:
* HHH-13727 ( https://hibernate.atlassian.net/browse/HHH-13727 ) Closed
* HHH-13597 ( https://hibernate.atlassian.net/browse/HHH-13597 ) Closed
( https://hibernate.atlassian.net/browse/HHH-13939#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-13939#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100124- sha1:c13ca0d )
4 years, 6 months
[JIRA] (HHH-13938) NullPointerException at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassDescriptor - Hibernate 6.0.0.Alpha4
by Victor Williams Stafusa da Silva (JIRA)
Victor Williams Stafusa da Silva ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=5e8c88d... ) *updated* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiMjcwM2MwNzNj... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-13938?atlOrigin=eyJpIjoiMjcwM2... ) HHH-13938 ( https://hibernate.atlassian.net/browse/HHH-13938?atlOrigin=eyJpIjoiMjcwM2... ) NullPointerException at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassDescriptor - Hibernate 6.0.0.Alpha4 ( https://hibernate.atlassian.net/browse/HHH-13938?atlOrigin=eyJpIjoiMjcwM2... )
Change By: Victor Williams Stafusa da Silva ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=5e8c88d... )
This code works fine in Hibernate 5.4.13.Final, but gives a NullPointerException at Hibernate 6.0.0.Alpha4:
Test file:
*HBug.java*
{code:java}package com.example;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.persistence.spi.PersistenceProvider;
import org.hibernate.SessionFactory;
import org.hibernate.jpa.HibernatePersistenceProvider;
/**
* @author Victor Williams Stafusa da Silva
*/
public class Hbug {
public static void main(String[] args) throws Exception {
Map<String, String> props = new HashMap<>();
props.put("javax.persistence.jdbc.user", "sa");
props.put("javax.persistence.jdbc.password", "");
props.put("javax.persistence.jdbc.url", "jdbc:hsqldb:mem:test1");
props.put("hibernate.hbm2ddl.import_files_sql_extractor", "org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor");
props.put("javax.persistence.schema-generation.database.action", "drop-and-create");
PersistenceProvider pp = new HibernatePersistenceProvider();
var spui = new SimplePersistenceUnitInfo(
Optional.empty(),
HibernatePersistenceProvider.class,
"test-1",
Set.of(Fruit.class),
props);
var emf = pp.createContainerEntityManagerFactory(spui, props);
if (!(emf instanceof SessionFactory)) throw new Exception("Bad EMF");
}
}{code}
Utilitary class used by the above one:
*SimplePersistenceUnitInfo.java*
{code:java}package com.example;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.stream.Collectors;
import javax.persistence.SharedCacheMode;
import javax.persistence.ValidationMode;
import javax.persistence.spi.ClassTransformer;
import javax.persistence.spi.PersistenceProvider;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
/**
* @author Victor Williams Stafusa da Silva
*/
public final class SimplePersistenceUnitInfo implements PersistenceUnitInfo {
private final Optional<URL> url;
private final Class<? extends PersistenceProvider> providerClass;
private final String persistenceUnitName;
private final List<String> classes;
private final Map<String, String> properties;
public SimplePersistenceUnitInfo(
/*@NonNull*/ Optional<URL> url,
/*@NonNull*/ Class<? extends PersistenceProvider> providerClass,
/*@NonNull*/ String persistenceUnitName,
/*@NonNull*/ Collection<Class<?>> classes,
/*@NonNull*/ Map<String, String> properties)
{
this.url = url;
this.providerClass = providerClass;
this.persistenceUnitName = persistenceUnitName;
this.classes = classes.stream().map(Class::getName).collect(Collectors.toList());
this.properties = new HashMap<>();
this.properties.putAll(properties);
}
@Override
public String getPersistenceUnitName() {
return persistenceUnitName;
}
@Override
public String getPersistenceProviderClassName() {
return providerClass.getName();
}
@Override
public PersistenceUnitTransactionType getTransactionType() {
return PersistenceUnitTransactionType.RESOURCE_LOCAL;
}
@Override
//@Nullable
public DataSource getJtaDataSource() {
return null;
}
@Override
//@Nullable
public DataSource getNonJtaDataSource() {
return null;
}
@Override
public List<String> getMappingFileNames() {
return Collections.emptyList();
}
@Override
public List<URL> getJarFileUrls() {
try {
return Collections.list(this.getClass().getClassLoader().getResources(""));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
//@Nullable
@Override
public URL getPersistenceUnitRootUrl() {
return url.orElse(null);
}
@Override
public List<String> getManagedClassNames() {
return Collections.unmodifiableList(classes);
}
@Override
public boolean excludeUnlistedClasses() {
return false;
}
@Override
public SharedCacheMode getSharedCacheMode() {
return SharedCacheMode.UNSPECIFIED;
}
@Override
public ValidationMode getValidationMode() {
return ValidationMode.AUTO;
}
@Override
public Properties getProperties() {
Properties p = new Properties();
p.putAll(properties);
return p;
}
@Override
public String getPersistenceXMLSchemaVersion() {
return "2.2";
}
@Override
//@Nullable
public ClassLoader getClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
@Override
public void addTransformer(ClassTransformer transformer) {
}
@Override
//@Nullable
public ClassLoader getNewTempClassLoader() {
return null;
}
}{code}
Sample entity class:
*Fruit.java*
{code:java}package com.example;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* @author Victor Williams Stafusa da Silva
*/
@Entity
@Table(name = "fruits")
public class Fruit implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String color;
public Fruit() {}
public Fruit(String name, String color) {
this.name = name;
this.color = color;
}
public String getName() {
return name;
}
public String getColor() {
return color;
}
}{code}
Gradle script to build that:
*build.gradle*
{code:java}apply plugin: 'java'
apply plugin: 'application'
group = 'com.example'
mainClassName = 'com.example.Hbug'
repositories {
jcenter()
}
dependencies {
implementation 'org.hsqldb:hsqldb:2.5.0'
//implementation 'org.hibernate:hibernate-core:5.4.13.Final'
implementation 'org.hibernate.orm:hibernate-core:6.0.0.Alpha4'
}{code}
Run the code above and a ` NullPointerException ` will be throw (with Hibernate 6.0.0.Alpha4). However, if the gradle file is changed to use Hibernate 5.4.13 (uncomment that line and comment the one for 6.0.0.Alpha4), then the code works as expected.
Here is the output, including the stack trace:
*output*
{code:java}Apr 07, 2020 7:19:53 AM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [name: test-1]
Apr 07, 2020 7:19:54 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {6.0.0.Alpha4}
Apr 07, 2020 7:19:54 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
Exception in thread "main" java.lang.NullPointerException
at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassDescriptor(ClassFileArchiveEntryHandler.java:84)
at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassDescriptor(ClassFileArchiveEntryHandler.java:67)
at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.handleEntry(ClassFileArchiveEntryHandler.java:53)
at org.hibernate.boot.archive.internal.JarFileBasedArchiveDescriptor.visitArchive(JarFileBasedArchiveDescriptor.java:147)
at org.hibernate.boot.archive.internal.JarProtocolArchiveDescriptor.visitArchive(JarProtocolArchiveDescriptor.java:59)
at org.hibernate.boot.archive.scan.spi.AbstractScannerImpl.scan(AbstractScannerImpl.java:40)
at org.hibernate.boot.model.process.internal.ScanningCoordinator.coordinateScan(ScanningCoordinator.java:74)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.prepare(MetadataBuildingProcess.java:97)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:243)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:169)
at org.hibernate.jpa.boot.spi.Bootstrap.getEntityManagerFactoryBuilder(Bootstrap.java:32)
at org.hibernate.jpa.boot.spi.Bootstrap.getEntityManagerFactoryBuilder(Bootstrap.java:89)
at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilder(HibernatePersistenceProvider.java:166)
at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:141)
at com.example.Hbug.main(Hbug.java:31){code}
P.S.: I'm running and compiling this using Java 13.0.2.
( https://hibernate.atlassian.net/browse/HHH-13938#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-13938#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100124- sha1:c13ca0d )
4 years, 6 months
[JIRA] (HHH-13938) NullPointerException at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassDescriptor - Hibernate 6.0.0.Alpha4
by Victor Williams Stafusa da Silva (JIRA)
Victor Williams Stafusa da Silva ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=5e8c88d... ) *updated* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiNTVmMjhiODJh... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-13938?atlOrigin=eyJpIjoiNTVmMj... ) HHH-13938 ( https://hibernate.atlassian.net/browse/HHH-13938?atlOrigin=eyJpIjoiNTVmMj... ) NullPointerException at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassDescriptor - Hibernate 6.0.0.Alpha4 ( https://hibernate.atlassian.net/browse/HHH-13938?atlOrigin=eyJpIjoiNTVmMj... )
Change By: Victor Williams Stafusa da Silva ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=5e8c88d... )
This code works fine in Hibernate 5.4.13.Final, but gives a ` NullPointerException ` at Hibernate 6.0.0.Alpha4:
Test file:
*HBug.java*
{code: title=HBug. java |borderStyle=solid }
package com.example;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.persistence.spi.PersistenceProvider;
import org.hibernate.SessionFactory;
import org.hibernate.jpa.HibernatePersistenceProvider;
/**
* @author Victor Williams Stafusa da Silva
*/
public class Hbug {
public static void main(String[] args) throws Exception {
Map<String, String> props = new HashMap<>();
props.put("javax.persistence.jdbc.user", "sa");
props.put("javax.persistence.jdbc.password", "");
props.put("javax.persistence.jdbc.url", "jdbc:hsqldb:mem:test1");
props.put("hibernate.hbm2ddl.import_files_sql_extractor", "org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor");
props.put("javax.persistence.schema-generation.database.action", "drop-and-create");
PersistenceProvider pp = new HibernatePersistenceProvider();
var spui = new SimplePersistenceUnitInfo(
Optional.empty(),
HibernatePersistenceProvider.class,
"test-1",
Set.of(Fruit.class),
props);
var emf = pp.createContainerEntityManagerFactory(spui, props);
if (!(emf instanceof SessionFactory)) throw new Exception("Bad EMF");
}
}
{code}
Utilitary class used by the above one:
*SimplePersistenceUnitInfo.java*
{code: title=SimplePersistenceUnitInfo. java |borderStyle=solid }
package com.example;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.stream.Collectors;
import javax.persistence.SharedCacheMode;
import javax.persistence.ValidationMode;
import javax.persistence.spi.ClassTransformer;
import javax.persistence.spi.PersistenceProvider;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
/**
* @author Victor Williams Stafusa da Silva
*/
public final class SimplePersistenceUnitInfo implements PersistenceUnitInfo {
private final Optional<URL> url;
private final Class<? extends PersistenceProvider> providerClass;
private final String persistenceUnitName;
private final List<String> classes;
private final Map<String, String> properties;
public SimplePersistenceUnitInfo(
/*@NonNull*/ Optional<URL> url,
/*@NonNull*/ Class<? extends PersistenceProvider> providerClass,
/*@NonNull*/ String persistenceUnitName,
/*@NonNull*/ Collection<Class<?>> classes,
/*@NonNull*/ Map<String, String> properties)
{
this.url = url;
this.providerClass = providerClass;
this.persistenceUnitName = persistenceUnitName;
this.classes = classes.stream().map(Class::getName).collect(Collectors.toList());
this.properties = new HashMap<>();
this.properties.putAll(properties);
}
@Override
public String getPersistenceUnitName() {
return persistenceUnitName;
}
@Override
public String getPersistenceProviderClassName() {
return providerClass.getName();
}
@Override
public PersistenceUnitTransactionType getTransactionType() {
return PersistenceUnitTransactionType.RESOURCE_LOCAL;
}
@Override
//@Nullable
public DataSource getJtaDataSource() {
return null;
}
@Override
//@Nullable
public DataSource getNonJtaDataSource() {
return null;
}
@Override
public List<String> getMappingFileNames() {
return Collections.emptyList();
}
@Override
public List<URL> getJarFileUrls() {
try {
return Collections.list(this.getClass().getClassLoader().getResources(""));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
//@Nullable
@Override
public URL getPersistenceUnitRootUrl() {
return url.orElse(null);
}
@Override
public List<String> getManagedClassNames() {
return Collections.unmodifiableList(classes);
}
@Override
public boolean excludeUnlistedClasses() {
return false;
}
@Override
public SharedCacheMode getSharedCacheMode() {
return SharedCacheMode.UNSPECIFIED;
}
@Override
public ValidationMode getValidationMode() {
return ValidationMode.AUTO;
}
@Override
public Properties getProperties() {
Properties p = new Properties();
p.putAll(properties);
return p;
}
@Override
public String getPersistenceXMLSchemaVersion() {
return "2.2";
}
@Override
//@Nullable
public ClassLoader getClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
@Override
public void addTransformer(ClassTransformer transformer) {
}
@Override
//@Nullable
public ClassLoader getNewTempClassLoader() {
return null;
}
}
{code}
Sample entity class:
*Fruit.java*
{code: title=Fruit. java |borderStyle=solid }
package com.example;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* @author Victor Williams Stafusa da Silva
*/
@Entity
@Table(name = "fruits")
public class Fruit implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String color;
public Fruit() {}
public Fruit(String name, String color) {
this.name = name;
this.color = color;
}
public String getName() {
return name;
}
public String getColor() {
return color;
}
}
{code}
Gradle script to build that:
{code:title= * build.gradle |borderStyle=solid} *
{code:java} apply plugin: 'java'
apply plugin: 'application'
group = 'com.example'
mainClassName = 'com.example.Hbug'
repositories {
jcenter()
}
dependencies {
implementation 'org.hsqldb:hsqldb:2.5.0'
//implementation 'org.hibernate:hibernate-core:5.4.13.Final'
implementation 'org.hibernate.orm:hibernate-core:6.0.0.Alpha4'
}
{code}
Run the code above and a `NullPointerException` will be throw (with Hibernate 6.0.0.Alpha4). However, if the gradle file is changed to use Hibernate 5.4.13 (uncomment that line and comment the one for 6.0.0.Alpha4), then the code works as expected.
Here is the output, including the stack trace:
*output*
{code: title=output|borderStyle=solid java }
Apr 07, 2020 7:19:53 AM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [name: test-1]
Apr 07, 2020 7:19:54 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {6.0.0.Alpha4}
Apr 07, 2020 7:19:54 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
Exception in thread "main" java.lang.NullPointerException
at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassDescriptor(ClassFileArchiveEntryHandler.java:84)
at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassDescriptor(ClassFileArchiveEntryHandler.java:67)
at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.handleEntry(ClassFileArchiveEntryHandler.java:53)
at org.hibernate.boot.archive.internal.JarFileBasedArchiveDescriptor.visitArchive(JarFileBasedArchiveDescriptor.java:147)
at org.hibernate.boot.archive.internal.JarProtocolArchiveDescriptor.visitArchive(JarProtocolArchiveDescriptor.java:59)
at org.hibernate.boot.archive.scan.spi.AbstractScannerImpl.scan(AbstractScannerImpl.java:40)
at org.hibernate.boot.model.process.internal.ScanningCoordinator.coordinateScan(ScanningCoordinator.java:74)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.prepare(MetadataBuildingProcess.java:97)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:243)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:169)
at org.hibernate.jpa.boot.spi.Bootstrap.getEntityManagerFactoryBuilder(Bootstrap.java:32)
at org.hibernate.jpa.boot.spi.Bootstrap.getEntityManagerFactoryBuilder(Bootstrap.java:89)
at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilder(HibernatePersistenceProvider.java:166)
at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:141)
at com.example.Hbug.main(Hbug.java:31)
{code}
P.S.: I'm running and compiling this using Java 13.0.2.
( https://hibernate.atlassian.net/browse/HHH-13938#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-13938#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100124- sha1:c13ca0d )
4 years, 6 months
[JIRA] (HHH-13938) NullPointerException at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassDescriptor - Hibernate 6.0.0.Alpha4
by Victor Williams Stafusa da Silva (JIRA)
Victor Williams Stafusa da Silva ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=5e8c88d... ) *created* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiYzE1Y2Q3NTlk... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-13938?atlOrigin=eyJpIjoiYzE1Y2... ) HHH-13938 ( https://hibernate.atlassian.net/browse/HHH-13938?atlOrigin=eyJpIjoiYzE1Y2... ) NullPointerException at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassDescriptor - Hibernate 6.0.0.Alpha4 ( https://hibernate.atlassian.net/browse/HHH-13938?atlOrigin=eyJpIjoiYzE1Y2... )
Issue Type: Bug Affects Versions: 6.0.0.Alpha4 Assignee: Unassigned Components: hibernate-core, regression Created: 07/Apr/2020 07:38 AM Environment: Hibernate 6.0.0.Alpha4
Java 13.0.4
Javac 13.0.4 Labels: regression Priority: Major Reporter: Victor Williams Stafusa da Silva ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=5e8c88d... )
This code works fine in Hibernate 5.4.13.Final, but gives a `NullPointerException` at Hibernate 6.0.0.Alpha4:
Test file:
*HBug.java*
package com.example;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.persistence.spi.PersistenceProvider;
import org.hibernate.SessionFactory;
import org.hibernate.jpa.HibernatePersistenceProvider;
/**
* @author Victor Williams Stafusa da Silva
*/
public class Hbug {
public static void main( String [] args) throws Exception {
Map< String , String > props = new HashMap<>();
props.put( "javax.persistence.jdbc.user" , "sa" );
props.put( "javax.persistence.jdbc.password" , "");
props.put( "javax.persistence.jdbc.url" , "jdbc:hsqldb:mem:test1" );
props.put( "hibernate.hbm2ddl.import_files_sql_extractor" , "org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor" );
props.put( "javax.persistence.schema-generation.database.action" , "drop-and-create" );
PersistenceProvider pp = new HibernatePersistenceProvider();
var spui = new SimplePersistenceUnitInfo(
Optional.empty(),
HibernatePersistenceProvider.class,
"test-1" ,
Set.of(Fruit.class),
props);
var emf = pp.createContainerEntityManagerFactory(spui, props);
if (!(emf instanceof SessionFactory)) throw new Exception( "Bad EMF" );
}
}
Utilitary class used by the above one:
*SimplePersistenceUnitInfo.java*
package com.example;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.stream.Collectors;
import javax.persistence.SharedCacheMode;
import javax.persistence.ValidationMode;
import javax.persistence.spi.ClassTransformer;
import javax.persistence.spi.PersistenceProvider;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
/**
* @author Victor Williams Stafusa da Silva
*/
public final class SimplePersistenceUnitInfo implements PersistenceUnitInfo {
private final Optional<URL> url;
private final Class <? extends PersistenceProvider> providerClass;
private final String persistenceUnitName;
private final List< String > classes;
private final Map< String , String > properties;
public SimplePersistenceUnitInfo(
/*@NonNull*/ Optional<URL> url,
/*@NonNull*/ Class <? extends PersistenceProvider> providerClass,
/*@NonNull*/ String persistenceUnitName,
/*@NonNull*/ Collection< Class <?>> classes,
/*@NonNull*/ Map< String , String > properties)
{
this.url = url;
this.providerClass = providerClass;
this.persistenceUnitName = persistenceUnitName;
this.classes = classes.stream().map( Class ::getName).collect(Collectors.toList());
this.properties = new HashMap<>();
this.properties.putAll(properties);
}
@Override
public String getPersistenceUnitName() {
return persistenceUnitName;
}
@Override
public String getPersistenceProviderClassName() {
return providerClass.getName();
}
@Override
public PersistenceUnitTransactionType getTransactionType() {
return PersistenceUnitTransactionType.RESOURCE_LOCAL;
}
@Override
//@Nullable
public DataSource getJtaDataSource() {
return null ;
}
@Override
//@Nullable
public DataSource getNonJtaDataSource() {
return null ;
}
@Override
public List< String > getMappingFileNames() {
return Collections.emptyList();
}
@Override
public List<URL> getJarFileUrls() {
try {
return Collections.list( this.getClass().getClassLoader().getResources(""));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
//@Nullable
@Override
public URL getPersistenceUnitRootUrl() {
return url.orElse( null );
}
@Override
public List< String > getManagedClassNames() {
return Collections.unmodifiableList(classes);
}
@Override
public boolean excludeUnlistedClasses() {
return false ;
}
@Override
public SharedCacheMode getSharedCacheMode() {
return SharedCacheMode.UNSPECIFIED;
}
@Override
public ValidationMode getValidationMode() {
return ValidationMode.AUTO;
}
@Override
public Properties getProperties() {
Properties p = new Properties();
p.putAll(properties);
return p;
}
@Override
public String getPersistenceXMLSchemaVersion() {
return "2.2" ;
}
@Override
//@Nullable
public ClassLoader getClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
@Override
public void addTransformer(ClassTransformer transformer) {
}
@Override
//@Nullable
public ClassLoader getNewTempClassLoader() {
return null ;
}
}
Sample entity class:
*Fruit.java*
package com.example;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* @author Victor Williams Stafusa da Silva
*/
@Entity
@Table(name = "fruits" )
public class Fruit implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String color;
public Fruit() {}
public Fruit( String name, String color) {
this.name = name;
this.color = color;
}
public String getName() {
return name;
}
public String getColor() {
return color;
}
}
Gradle script to build that:
*build.gradle*
apply plugin: 'java'
apply plugin: 'application'
group = 'com.example'
mainClassName = 'com.example.Hbug'
repositories {
jcenter()
}
dependencies {
implementation 'org.hsqldb:hsqldb:2.5.0'
//implementation 'org.hibernate:hibernate-core:5.4.13.Final'
implementation 'org.hibernate.orm:hibernate-core:6.0.0.Alpha4'
}
Run the code above and a `NullPointerException` will be throw (with Hibernate 6.0.0.Alpha4). However, if the gradle file is changed to use Hibernate 5.4.13 (uncomment that line and comment the one for 6.0.0.Alpha4), then the code works as expected.
Here is the output, including the stack trace:
*output*
Apr 07, 2020 7:19:53 AM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [name: test-1]
Apr 07, 2020 7:19:54 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {6.0.0.Alpha4}
Apr 07, 2020 7:19:54 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
Exception in thread "main" java.lang.NullPointerException
at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassDescriptor(ClassFileArchiveEntryHandler.java:84)
at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassDescriptor(ClassFileArchiveEntryHandler.java:67)
at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.handleEntry(ClassFileArchiveEntryHandler.java:53)
at org.hibernate.boot.archive.internal.JarFileBasedArchiveDescriptor.visitArchive(JarFileBasedArchiveDescriptor.java:147)
at org.hibernate.boot.archive.internal.JarProtocolArchiveDescriptor.visitArchive(JarProtocolArchiveDescriptor.java:59)
at org.hibernate.boot.archive.scan.spi.AbstractScannerImpl.scan(AbstractScannerImpl.java:40)
at org.hibernate.boot.model.process.internal.ScanningCoordinator.coordinateScan(ScanningCoordinator.java:74)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.prepare(MetadataBuildingProcess.java:97)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:243)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:169)
at org.hibernate.jpa.boot.spi.Bootstrap.getEntityManagerFactoryBuilder(Bootstrap.java:32)
at org.hibernate.jpa.boot.spi.Bootstrap.getEntityManagerFactoryBuilder(Bootstrap.java:89)
at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilder(HibernatePersistenceProvider.java:166)
at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:141)
at com.example.Hbug.main(Hbug.java:31)
P.S.: I'm running and compiling this using Java 13.0.2.
( https://hibernate.atlassian.net/browse/HHH-13938#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-13938#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100124- sha1:c13ca0d )
4 years, 6 months