Skip to content

Commit 1c9976d

Browse files
committed
HHH-10131 - CacheableFileXmlSource.doBind returns null instead of created binding when .hbm.xml.bin have not been created yet
(cherry picked from commit ed89297)
1 parent cf47c8d commit 1c9976d

File tree

4 files changed

+216
-15
lines changed

4 files changed

+216
-15
lines changed

hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/CacheableFileXmlSource.java

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import org.hibernate.boot.MappingException;
1616
import org.hibernate.boot.jaxb.Origin;
17+
import org.hibernate.boot.jaxb.SourceType;
1718
import org.hibernate.boot.jaxb.spi.Binder;
1819
import org.hibernate.boot.jaxb.spi.Binding;
1920
import org.hibernate.boot.jaxb.spi.XmlSource;
@@ -39,20 +40,23 @@ public CacheableFileXmlSource(Origin origin, File xmlFile, boolean strict) {
3940

4041
this.serFile = determineCachedFile( xmlFile );
4142

42-
final boolean useCachedFile = xmlFile.exists()
43-
&& serFile.exists()
44-
&& xmlFile.lastModified() < serFile.lastModified();
45-
46-
if ( strict && !useCachedFile ) {
47-
throw new MappingException(
48-
String.format( "Cached file [%s] could not be found or could not be used", origin.getName() ),
49-
origin
50-
);
43+
if ( strict ) {
44+
if ( !serFile.exists() ) {
45+
throw new MappingException(
46+
String.format( "Cached file [%s] could not be found", origin.getName() ),
47+
origin
48+
);
49+
}
50+
if ( xmlFile.exists() && xmlFile.lastModified() > serFile.lastModified() ) {
51+
throw new MappingException(
52+
String.format( "Cached file [%s] could not be used as the mapping file is newer", origin.getName() ),
53+
origin
54+
);
55+
}
5156
}
52-
5357
}
5458

55-
private static File determineCachedFile(File xmlFile) {
59+
public static File determineCachedFile(File xmlFile) {
5660
return new File( xmlFile.getAbsolutePath() + ".bin" );
5761
}
5862

@@ -90,12 +94,12 @@ public Binding doBind(Binder binder) {
9094
}
9195

9296
log.readingMappingsFromFile( xmlFile.getPath() );
93-
final Object binding = FileXmlSource.doBind( binder, xmlFile, getOrigin() );
97+
final Binding binding = FileXmlSource.doBind( binder, xmlFile, getOrigin() );
9498

9599
writeSerFile( binding );
96-
}
97100

98-
return null;
101+
return binding;
102+
}
99103
}
100104

101105
private <T> T readSerFile() throws SerializationException, FileNotFoundException {
@@ -104,14 +108,30 @@ private <T> T readSerFile() throws SerializationException, FileNotFoundException
104108
}
105109

106110
private void writeSerFile(Object binding) {
111+
writeSerFile( (Serializable) binding, xmlFile, serFile );
112+
}
113+
114+
private static void writeSerFile(Serializable binding, File xmlFile, File serFile) {
107115
try {
108116
log.debugf( "Writing cache file for: %s to: %s", xmlFile.getAbsolutePath(), serFile.getAbsolutePath() );
109-
SerializationHelper.serialize( (Serializable) binding, new FileOutputStream( serFile ) );
117+
SerializationHelper.serialize( binding, new FileOutputStream( serFile ) );
118+
boolean success = serFile.setLastModified( System.currentTimeMillis() );
119+
if ( !success ) {
120+
log.warn( "Could not update cacheable hbm.xml bin file timestamp" );
121+
}
110122
}
111123
catch ( Exception e ) {
112124
log.unableToWriteCachedFile( serFile.getAbsolutePath(), e.getMessage() );
113125
}
114126
}
115127

128+
public static void createSerFile(File xmlFile, Binder binder) {
129+
final Origin origin = new Origin( SourceType.FILE, xmlFile.getAbsolutePath() );
130+
writeSerFile(
131+
FileXmlSource.doBind( binder, xmlFile, origin ),
132+
xmlFile,
133+
determineCachedFile( xmlFile )
134+
);
135+
}
116136

117137
}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.test.boot.binding.cacheable;
8+
9+
import java.io.File;
10+
import java.io.FileNotFoundException;
11+
import java.net.URL;
12+
13+
import org.hibernate.boot.MappingException;
14+
import org.hibernate.boot.Metadata;
15+
import org.hibernate.boot.MetadataSources;
16+
import org.hibernate.boot.jaxb.internal.CacheableFileXmlSource;
17+
import org.hibernate.boot.jaxb.internal.MappingBinder;
18+
import org.hibernate.boot.registry.StandardServiceRegistry;
19+
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
20+
import org.hibernate.boot.spi.XmlMappingBinderAccess;
21+
22+
import org.junit.After;
23+
import org.junit.Before;
24+
import org.junit.Test;
25+
26+
import org.jboss.logging.Logger;
27+
28+
import static org.junit.Assert.fail;
29+
30+
/**
31+
* Originally developed to help diagnose HHH-10131 - the original tests
32+
* check 4 conditions:<ol>
33+
* <li>strict usage where the cached file does exist</li>
34+
* <li>strict usage where the cached file does not exist</li>
35+
* <li>non-strict usage where the cached file does exist</li>
36+
* <li>non-strict usage where the cached file does not exist</li>
37+
* </ol>
38+
*
39+
* @author Steve Ebersole
40+
*/
41+
public class CacheableHbmXmlTest {
42+
private static final Logger log = Logger.getLogger( CacheableHbmXmlTest.class );
43+
44+
private static final String HBM_RESOURCE_NAME = "org/hibernate/test/boot/binding/cacheable/SimpleEntity.hbm.xml";
45+
46+
private StandardServiceRegistry ssr;
47+
private MappingBinder binder;
48+
49+
private File hbmXmlFile;
50+
private File hbmXmlBinFile;
51+
52+
@Before
53+
public void before() throws Exception {
54+
ssr = new StandardServiceRegistryBuilder()
55+
.build();
56+
binder = new XmlMappingBinderAccess( ssr ).getMappingBinder();
57+
58+
final URL hbmXmlUrl = getClass().getClassLoader().getResource( HBM_RESOURCE_NAME );
59+
if ( hbmXmlUrl == null ) {
60+
throw couldNotFindHbmXmlFile();
61+
}
62+
hbmXmlFile = new File( hbmXmlUrl.getFile() );
63+
if ( ! hbmXmlFile.exists() ) {
64+
throw couldNotFindHbmXmlFile();
65+
}
66+
hbmXmlBinFile = CacheableFileXmlSource.determineCachedFile( hbmXmlFile );
67+
}
68+
69+
private Exception couldNotFindHbmXmlFile() {
70+
throw new IllegalStateException( "Could not locate hbm.xml file by resource lookup" );
71+
}
72+
73+
@After
74+
public void after() {
75+
if ( ssr != null ) {
76+
StandardServiceRegistryBuilder.destroy( ssr );
77+
}
78+
}
79+
80+
@Test
81+
public void testStrictCaseWhereFileDoesPreviouslyExist() throws FileNotFoundException {
82+
deleteBinFile();
83+
createBinFile();
84+
try {
85+
new MetadataSources( ssr ).addCacheableFileStrictly( hbmXmlFile ).buildMetadata();
86+
}
87+
catch (MappingException e) {
88+
fail( "addCacheableFileStrictly led to MappingException when bin file existed" );
89+
}
90+
}
91+
92+
@Test
93+
public void testStrictCaseWhereFileDoesNotPreviouslyExist() throws FileNotFoundException {
94+
deleteBinFile();
95+
try {
96+
new MetadataSources( ssr ).addCacheableFileStrictly( hbmXmlFile ).buildMetadata();
97+
fail( "addCacheableFileStrictly should be led to MappingException when bin file does not exist" );
98+
}
99+
catch (MappingException ignore) {
100+
// this is the expected result
101+
}
102+
}
103+
104+
@Test
105+
public void testNonStrictCaseWhereFileDoesPreviouslyExist() {
106+
deleteBinFile();
107+
createBinFile();
108+
new MetadataSources( ssr ).addCacheableFile( hbmXmlFile ).buildMetadata();
109+
}
110+
111+
@Test
112+
public void testNonStrictCaseWhereFileDoesNotPreviouslyExist() {
113+
deleteBinFile();
114+
new MetadataSources( ssr ).addCacheableFile( hbmXmlFile ).buildMetadata();
115+
}
116+
117+
private void deleteBinFile() {
118+
// if it exists
119+
if ( hbmXmlBinFile.exists() ) {
120+
final boolean success = hbmXmlBinFile.delete();
121+
if ( !success ) {
122+
log.warn( "Unable to delete existing cached hbm.xml.bin file", new Exception() );
123+
}
124+
}
125+
}
126+
127+
private void createBinFile() {
128+
if ( hbmXmlBinFile.exists() ) {
129+
log.warn( "Cached hbm.xml.bin file already existed on request to create", new Exception() );
130+
}
131+
else {
132+
CacheableFileXmlSource.createSerFile( hbmXmlFile, binder );
133+
}
134+
}
135+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.test.boot.binding.cacheable;
8+
9+
/**
10+
* @author Steve Ebersole
11+
*/
12+
public class SimpleEntity {
13+
private Long id;
14+
private String name;
15+
16+
public Long getId() {
17+
return id;
18+
}
19+
20+
public void setId(Long id) {
21+
this.id = id;
22+
}
23+
24+
public String getName() {
25+
return name;
26+
}
27+
28+
public void setName(String name) {
29+
this.name = name;
30+
}
31+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
~ Hibernate, Relational Persistence for Idiomatic Java
4+
~
5+
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
6+
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
7+
-->
8+
<hibernate-mapping xmlns="http://www.hibernate.org/xsd/hibernate-mapping" package="org.hibernate.test.boot.binding.cacheable">
9+
<class name="SimpleEntity">
10+
<id name="id" column="id" type="java.lang.Long">
11+
<generator class="increment"/>
12+
</id>
13+
<property name="name" type="string"/>
14+
</class>
15+
</hibernate-mapping>

0 commit comments

Comments
 (0)