Announcement Announcement Module
Collapse
No announcement yet.
support for transient fields? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • support for transient fields?

    Hello,

    do you plan on including support for transient fields in the next version?

    Regards

  • #2
    Just commenting, but I thought it already does. If you don't want a property to be mapped make it transient.

    From the docs

    "Transient fields are not persisted."

    Mark

    Comment


    • #3
      I though that as well, however when I marked a property to be transient I got this exception:

      org.springframework.core.convert.ConversionFailedE xception: Unable to convert value "null" from type 'null' to type 'double';

      Backtracing the stack trace I got to the Neo4JPersistentPropertyImpl.java where the isTransient() method returns always false:
      https://github.com/SpringSource/spri...pertyImpl.java (line 306).
      And there is the isReallyTransient() method that seems to do the job, but is used nowhere...

      Comment


      • #4
        Hmm, there is a comment in the isReallyTransient about it being deprecated, and I see the return false in isTransient. Even though isReallyTransient is not used, I noticed the code also would look for java.perisitence.Transient annotation. Can you try putting that annotation on that property and just see what happens. I doubt it will work, but you can always quickly try.

        Mark

        Comment


        • #5
          Hi Mark,
          thanks for the reply. I gave both the java.persistence.Transient and the org.springframework.data.annotation.Transient a go to no avail. By the way the base class (AbstractPersistentProperty) has a (seemingly) working implementation for the isTransient() method and I dunno why it was overwritten... So I forked the repo, fixed it and send a pull request... I cant see a valid reason why the method always returns false (when every tutorial out there claims that transient fields are not persisted), I hope I didnt overlook something.

          Comment


          • #6
            Hey,

            the problem is that the isTransient in AbstractPersistentProperty just excludes them from the properties, sometimes (e.g. in Cross-Store mode we still need to access those fields as they might have been made transient for JPA to ignore them.)

            Will look into that anyway, could you please raise a JIRA issue (http://spring.neo4j.org/issues) to track it (and relate to this thread).

            Thanks a lot

            Michael

            Comment


            • #7
              Btw. isReallyTransient is used here:


              TransientFieldAccessorFactory
              public boolean accept(final Neo4jPersistentProperty property) {
              return property.isReallyTransient();
              }

              Comment


              • #8
                Okay, I understand the potential cross-store issue, but why does the documentation state that non-persistable fields are supported when in fact they arent (see the exception below)?

                Comment


                • #9
                  They should be supported just fine, which exception / error do you encounter?

                  Michael

                  Comment


                  • #10
                    Michael, he posted it earlier in the thread. He is getting a ConversionFailedException on that property he has as transient. So while it looks like the database doesn't store the data for that field, when you retrieve data and then go to populate the object, it is still trying to set the transient value to null. And since that property is a primitive type double, whammo! Can't assign null to a primitive.

                    s7orm, you could change that property to Double instead of double, just to get rid of the exception.

                    Then to check if transient is being supported in your case by setting a value to that property, saving it in the database, then retrieving it and seeing if that property is populated or set to null.

                    Mark

                    Comment


                    • #11
                      Hi,
                      I have another issue with transient fields. In my case I want to initialize transient field by constructor when loading from repository but it is null regardless. I have similar situation on transient JPA entities, where it is ok.
                      This is my simplified test:

                      Code:
                      import static org.hamcrest.CoreMatchers.notNullValue;
                      import static org.hamcrest.CoreMatchers.equalTo;
                      import static org.hamcrest.CoreMatchers.not;
                      import static org.hamcrest.Matchers.sameInstance;
                      import static org.junit.Assert.assertThat;
                      
                      import java.beans.PropertyChangeListener;
                      import java.beans.PropertyChangeSupport;
                      
                      import javax.persistence.Transient;
                      
                      import org.junit.Test;
                      import org.junit.runner.RunWith;
                      import org.springframework.beans.factory.annotation.Autowired;
                      import org.springframework.data.neo4j.annotation.GraphId;
                      import org.springframework.data.neo4j.annotation.NodeEntity;
                      import org.springframework.data.neo4j.support.Neo4jTemplate;
                      import org.springframework.data.neo4j.support.node.Neo4jHelper;
                      import org.springframework.test.context.ContextConfiguration;
                      import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
                      import org.springframework.test.context.transaction.BeforeTransaction;
                      import org.springframework.transaction.annotation.Transactional;
                      
                      @RunWith(SpringJUnit4ClassRunner.class)
                      @ContextConfiguration
                      public class TransientTest {
                      
                      	@Autowired
                      	private Neo4jTemplate template;
                      
                      	@BeforeTransaction
                      	public void setUp() {
                      			Neo4jHelper.cleanDb(template);
                      	}
                      	
                      	@Test
                      	@Transactional
                      	public void transientTest(){
                      		TestEntity entity = new TestEntity();
                      		entity.setValue("value");
                      		TestEntity persistedEntity = template.save(entity);
                      		assertThat(persistedEntity.getId(), notNullValue());
                      		assertThat(persistedEntity.pcs, notNullValue());
                      		assertThat(persistedEntity.pcs, not(sameInstance(entity.pcs)));
                      		assertThat(persistedEntity.getValue(), equalTo(entity.getValue()));
                      		
                      	}
                      	
                      	@NodeEntity
                      	public static class TestEntity {
                      		@Transient
                      		private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
                      
                      		@GraphId
                      		Long id;
                      		String value;
                      
                      		public Long getId() {
                      			return id;
                      		}
                      
                      		public void setId(Long id) {
                      			Long oldValue = this.id;
                      			this.id = id;
                      			pcs.firePropertyChange("id", oldValue, id);
                      		}
                      
                      		public String getValue() {
                      			return value;
                      		}
                      
                      		public void setValue(String value) {
                      			String oldValue = this.value;
                      			this.value = value;
                      			pcs.firePropertyChange("value", oldValue, value);
                      		}
                      
                      		public void addPropertyChangeListener(PropertyChangeListener listener) {
                      			pcs.addPropertyChangeListener(listener);
                      		}
                      
                      		public void removePropertyChangeListener(PropertyChangeListener listener) {
                      			pcs.removePropertyChangeListener(listener);
                      		}
                      	}
                      }
                      I have now workaround by lazy initialization when first PropertyChangeListener is added and null check before firePropertyChange. Is there another solution or some plans to support initialization on construct?

                      Comment

                      Working...
                      X