-
Notifications
You must be signed in to change notification settings - Fork 166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#437 - AutoIndex label NPE during initialization and index lookup #484
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,10 +13,12 @@ | |
|
||
package org.neo4j.ogm.context; | ||
|
||
import static java.util.Objects.*; | ||
|
||
import org.neo4j.ogm.metadata.ClassInfo; | ||
|
||
import java.util.Objects; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
/** | ||
* Pair of label and primary id to use for lookups by primary key in MappingContext and CypherContext | ||
* The label is needed because primary id is unique for given label. There might be 1 primary id pointing to | ||
|
@@ -33,11 +35,11 @@ class LabelPrimaryId { | |
/** | ||
* Create LabelPrimaryId | ||
* | ||
* @param classInfo class info containign the primary id | ||
* @param classInfo class info containing the primary id | ||
* @param id the value of the id | ||
*/ | ||
public LabelPrimaryId(ClassInfo classInfo, Object id) { | ||
this.label = classInfo.primaryIndexField().containingClassInfo().neo4jName(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change here - as much as I understand it to be in accordance with the docs - does change behavior for everyone that relays on having the 1st label being the parent or containing class. What do u think @meistermeier ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this change is a key aspect of this fix, I'd suggest to communicate it properly during the next release update in a way it gives enough information for those relaying on the buggy behavior. |
||
this.label = classInfo.neo4jName(); | ||
this.id = requireNonNull(id); | ||
} | ||
|
||
|
@@ -49,32 +51,22 @@ public Object getId() { | |
return id; | ||
} | ||
|
||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) | ||
return true; | ||
if (o == null || getClass() != o.getClass()) | ||
return false; | ||
|
||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
LabelPrimaryId that = (LabelPrimaryId) o; | ||
|
||
if (!label.equals(that.label)) | ||
return false; | ||
return id.equals(that.id); | ||
return Objects.equals(label, that.label) && Objects.equals(id, that.id); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
int result = label.hashCode(); | ||
result = 31 * result + id.hashCode(); | ||
return result; | ||
return Objects.hash(label, id); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "LabelPrimaryId{" + | ||
"label='" + label + '\'' + | ||
", id=" + id + | ||
'}'; | ||
return String.format("LabelPrimaryId{label='%s', id=%s}", label, id); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,11 +13,6 @@ | |
|
||
package org.neo4j.ogm.session; | ||
|
||
import static java.util.Objects.*; | ||
|
||
import java.util.List; | ||
import java.util.concurrent.CopyOnWriteArrayList; | ||
|
||
import org.neo4j.ogm.autoindex.AutoIndexManager; | ||
import org.neo4j.ogm.config.Configuration; | ||
import org.neo4j.ogm.driver.Driver; | ||
|
@@ -28,6 +23,11 @@ | |
import org.neo4j.ogm.metadata.reflect.ReflectionEntityInstantiator; | ||
import org.neo4j.ogm.session.event.EventListener; | ||
|
||
import java.util.List; | ||
import java.util.concurrent.CopyOnWriteArrayList; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
/** | ||
* This is the main initialization point of OGM. Used to create {@link Session} instances for interacting with Neo4j. | ||
* In a typical scenario one instance of SessionFactory is created, shared across whole application. | ||
|
@@ -81,9 +81,7 @@ public SessionFactory(Configuration configuration, String... packages) { | |
this.driver = newDriverInstance(configuration.getDriverClassName()); | ||
this.driver.configure(configuration); | ||
this.eventListeners = new CopyOnWriteArrayList<>(); | ||
Neo4jSession session = (Neo4jSession) openSession(); | ||
AutoIndexManager autoIndexManager = new AutoIndexManager(this.metaData, configuration, session); | ||
autoIndexManager.build(); | ||
new AutoIndexManager(this.metaData, configuration, this); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See comment above, should have gone here. That should be an explicit method call making it clear that it is necessary. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as below. |
||
this.entityInstantiator = new ReflectionEntityInstantiator(metaData); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,19 +13,7 @@ | |
|
||
package org.neo4j.ogm.autoindex; | ||
|
||
import static com.google.common.collect.Lists.*; | ||
import static java.util.stream.Collectors.*; | ||
import static org.assertj.core.api.Assertions.*; | ||
|
||
import java.io.File; | ||
import java.io.FileInputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.function.Consumer; | ||
import java.util.stream.StreamSupport; | ||
|
||
import com.google.common.collect.ObjectArrays; | ||
import org.apache.commons.io.IOUtils; | ||
import org.junit.After; | ||
import org.junit.Before; | ||
|
@@ -37,16 +25,28 @@ | |
import org.neo4j.graphdb.schema.IndexDefinition; | ||
import org.neo4j.ogm.config.Configuration; | ||
import org.neo4j.ogm.metadata.MetaData; | ||
import org.neo4j.ogm.session.Neo4jSession; | ||
import org.neo4j.ogm.session.SessionFactory; | ||
import org.neo4j.ogm.testutil.MultiDriverTestClass; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import com.google.common.collect.ObjectArrays; | ||
import java.io.File; | ||
import java.io.FileInputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.function.Consumer; | ||
import java.util.stream.StreamSupport; | ||
|
||
import static com.google.common.collect.Lists.newArrayList; | ||
import static java.util.stream.Collectors.toList; | ||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
|
||
/** | ||
* Must not end with "Test" so it does not run on TC. | ||
* | ||
* @author Frantisek Hartman | ||
*/ | ||
public abstract class BaseAutoIndexManagerTestClass extends MultiDriverTestClass { | ||
|
@@ -204,9 +204,7 @@ public void testAutoIndexDumpCreatesIndex() throws IOException { | |
.generatedIndexesOutputFilename(file.getName()) | ||
.build(); | ||
|
||
Neo4jSession session = (Neo4jSession) sessionFactory.openSession(); | ||
AutoIndexManager indexManager = new AutoIndexManager(metaData, configuration, session); | ||
indexManager.build(); | ||
new AutoIndexManager(metaData, configuration, sessionFactory); | ||
|
||
assertThat(file.exists()).isTrue(); | ||
try (InputStream is = new FileInputStream(file)) { | ||
|
@@ -221,9 +219,7 @@ public void testAutoIndexDumpCreatesIndex() throws IOException { | |
|
||
void runAutoIndex(String mode) { | ||
Configuration configuration = getBaseConfiguration().autoIndex(mode).build(); | ||
Neo4jSession session = (Neo4jSession) sessionFactory.openSession(); | ||
AutoIndexManager indexManager = new AutoIndexManager(metaData, configuration, session); | ||
indexManager.build(); | ||
new AutoIndexManager(metaData, configuration, sessionFactory); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd rather prefer a solution not having the call to auto index manager here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand the concerns and I'd say it's a valid point for a later improvement and should be out-of-scope for this PR, since it will require more work, increase complexity and does not bring value to this particular PR main goal. As I mentioned before, this change was a minor improvement regarding the usage of the sessionFactory. |
||
} | ||
|
||
void executeForIndexes(Consumer<List<IndexDefinition>> consumer) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package org.neo4j.ogm.domain.abstraction; | ||
|
||
public abstract class AnotherEntity extends Entity { | ||
|
||
protected String anotherValue; | ||
|
||
public AnotherEntity() { | ||
super(); | ||
} | ||
|
||
public AnotherEntity(String uuid) { | ||
super(uuid); | ||
} | ||
|
||
public String getAnotherValue() { | ||
return anotherValue; | ||
} | ||
|
||
public void setAnotherValue(String anotherValue) { | ||
this.anotherValue = anotherValue; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package org.neo4j.ogm.domain.abstraction; | ||
|
||
import java.util.HashSet; | ||
import java.util.Set; | ||
|
||
public class ChildA extends Entity { | ||
|
||
private String value; | ||
|
||
private Set<AnotherEntity> children = new HashSet<>(); | ||
|
||
public ChildA() { | ||
super(); | ||
} | ||
|
||
public ChildA(String uuid) { | ||
super(uuid); | ||
} | ||
|
||
public ChildA add(AnotherEntity childB) { | ||
children.add(childB); | ||
return this; | ||
} | ||
|
||
public String getValue() { | ||
return value; | ||
} | ||
|
||
public void setValue(String value) { | ||
this.value = value; | ||
} | ||
|
||
public Set<AnotherEntity> getChildren() { | ||
return children; | ||
} | ||
|
||
public void setChildren(Set<AnotherEntity> children) { | ||
this.children = children; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That should be in the controlling structure, that is the one that executes the auto manager (or not).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please point out the controlling structure location?