Spring merge - java.sql.SQLException: Invalid column index - spring

I have a table that has 2 columns that create the primary key:
#Entity
#Table(name="DW.DW$SF$MONTHLY")
public class DWMonthly implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId DWMonthlyPK monthlyPK;
#Id
#Column(name="AID", insertable=false, updatable=false)
#IndexColumn(name="DW$SF$MONTHLY_PK")
private Long id;
#Column(name="CHNG_STATUS")
private BigDecimal chngStatus;
#Column(name="NAR")
private BigDecimal nar;
#Column(name="SF_AMID")
private String sfAmid;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="N_DATE", insertable=false, updatable=false)
#IndexColumn(name="DW$SF$MONTHLY_PK")
private Date nDate;
public DWMonthly() {}
public DWMonthly(Long id, String sfAmid, Date nDate) {
this.id = id;
this.sfAmid = sfAmid;
this.nDate = nDate;
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public BigDecimal getChngStatus() {
return this.chngStatus;
}
public void setChngStatus(BigDecimal chngStatus) {
this.chngStatus = chngStatus;
}
public BigDecimal getNar() {
return this.nar;
}
public void setNar(BigDecimal nar) {
this.nar = nar;
}
public String getSfAmid() {
return this.sfAmid;
}
public void setSfAmid(String sfAmid) {
this.sfAmid = sfAmid;
}
public Date getNDate() {
return nDate;
}
public void setNarDate(Date nDate) {
this.nDate = nDate;
}
}
Embeddable table:
#Embeddable
public class DWMonthlyPK implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name="AID")
private long aid;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="N_DATE")
private java.util.Date nDate;
public DWMonthlyPK() {
}
public long getAid() {
return this.aid;
}
public void setAid(long aid) {
this.aid = aid;
}
public java.util.Date getNDate() {
return this.narDate;
}
public void setNDate(java.util.Date nDate) {
this.nDate = nDate;
}
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof DWMonthlyPK)) {
return false;
}
DWMonthlyPK castOther = (DWMonthlyPK)other;
return
(this.aid == castOther.aid)
&& this.nDate.equals(castOther.nDate);
}
public int hashCode() {
final int prime = 31;
int hash = 17;
hash = hash * prime + ((int) (this.aid ^ (this.aid >>> 32)));
hash = hash * prime + this.nDate.hashCode();
return hash;
}
}
Find the record and update:
#Repository(value="MonthlyNarDaoRepository")
#Import({JpaConfigurationImpl.class})
#Transactional(value="dwTransactionManager",readOnly = true, propagation=Propagation.REQUIRES_NEW)
public class MonthlyNarDaoImpl implements MonthlyNarDao {
#Override
#Transactional(value="dwTransactionManager")
public void findAndUpdateMonhtlyByAccountId(Map<DWAccount, UpsertResult> accountsLoadedResult) {
for (DWAccount dwAccount : accountsLoadedResult.keySet()){
try {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<DWMonthlyNar> criteriaQuery = criteriaBuilder.createQuery(DWMonthlyNar.class);
Root<DWMonthlyNar> root = criteriaQuery.from(DWMonthlyNar.class);
Predicate p = criteriaBuilder.conjunction();
p = criteriaBuilder.and(criteriaBuilder.equal(root.get("id"), dwAccount.getId()), criteriaBuilder.notEqual(root.get("nar").as(BigDecimal.class), new BigDecimal(0.0)), criteriaBuilder.isNull(root.get("sfAmid")));
criteriaQuery.select(root);
criteriaQuery.where(p);
for (DWMonthlyNar dwMonthlyNar : this.entityManager.createQuery(criteriaQuery).getResultList()){
if (dwMonthlyNar.getSfAmid()==null || !dwMonthlyNar.getSfAmid().equals(accountsLoadedResult.get(dwAccount).getId())){
dwMonthlyNar.setSfAmid(accountsLoadedResult.get(dwAccount).getId());
this.entityManager.merge(dwMonthlyNar);
}
}
} catch (Exception e) {
logger.error("MonthlyNarDaoImpl.findAndUpdateMonhtlyNarByAccountId(): " + e.getMessage());
}
}
}
}
Error:
Hibernate: update DW.DW$SF$MONTHLY set CHNG_STATUS=?, NAR=?,
SF_AMID=? where AID=? and NAR_DATE=? 16:04:58.864 [main] DEBUG
o.h.e.jdbc.spi.SqlExceptionHelper - Invalid column index [n/a]
java.sql.SQLException: Invalid column index

Related

Count number of Item using Hibernate/JPA or JdbcTemplate

I am new to Spring/Hibernate/JPA. I have an entity class MovieEntity and MovieVersionEntity. MovieEntity has few details about the movie (like genre of movie) but MovieVersionEntity has more details about it (name, director...). So I want to count the number of movies (MovieVersionEntity) associated to the MovieEntity for the given type.
MovieEntity:
#Entity(name="MovieEntity")
#Table(name="Movie")
public class MovieEntity {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="Id")
private long id;
#Column(name="IsDeleted")
private boolean isDeleted;
#Column(name="ModifiedDate")
#Temporal(TemporalType.TIMESTAMP)
private Date modifiedDate;
#OneToOne()
#JoinColumn(name="MovieTypeId")
private MovieTypeEntity movieTypeEntity;
#OneToMany(mappedBy="movieEntity",optional = false)
private List<MovieVersionEntity> movieVersionEntity;
#Transient
//#Formula("select count(*) from movie_version mv where mv.id=id")
private int childCount;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public boolean isDeleted() {
return isDeleted;
}
public void setDeleted(boolean isDeleted) {
this.isDeleted = isDeleted;
}
public MovieTypeEntity getMovieTypeEntity() {
return movieTypeEntity;
}
public void setMovieTypeEntity(MovieTypeEntity movieTypeEntity) {
this.movieTypeEntity = movieTypeEntity;
}
public Date getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(Date modifiedDate) {
this.modifiedDate = modifiedDate;
}
public MovieVersionEntity getMovieVersionEntity() {
return movieVersionEntity;
}
public void setMovieVersionEntity(MovieVersionEntity movieVersionEntity) {
this.movieVersionEntity = movieVersionEntity;
}
public int getChildCount() {
return childCount;
}
public void setChildCount(int childCount) {
this.childCount = childCount;
}
}
MovieVersionEntity
#Entity(name = "MovieVersionEntity")
#Table(name="MovieVersion")
//#EntityListeners(AuditingEntityListener.class)
public class MovieVersionEntity {
#Id()
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="MovieId")
private long movieId;
#NotBlank
#Column(name="MovieName")
private String movieName;
#NotBlank
#Column(name="DirectorName")
private String directorName;
#NotBlank
#Column(name="Description")
private String description;
#Column(name="StopDate")
#Temporal(TemporalType.TIMESTAMP)
private Date stopDate;
#Column(name="DoneWatching")
private boolean doneWatching;
#Column(name="WatchDate")
#Temporal(TemporalType.TIMESTAMP)
//#CreatedDate
private Date watchDate;
#Column(name="ModifiedDate")
#Temporal(TemporalType.TIMESTAMP)
//#LastModifiedDate
private Date modifiedDate;
#ManyToOne(optional = false)
#JoinColumn(name="Id")
private MovieEntity movieEntity;
public String getMovieName() {
return movieName;
}
public void setMovieName(String movieName) {
this.movieName = movieName;
}
public String getDirectorName() {
return directorName;
}
public void setDirectorName(String directorName) {
this.directorName = directorName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getStopDate() {
return stopDate;
}
public void setStopDate(Date stopDate) {
this.stopDate = stopDate;
}
public boolean isDoneWatching() {
return doneWatching;
}
public void setDoneWatching(boolean doneWatching) {
this.doneWatching = doneWatching;
}
public Date getWatchDate() {
return watchDate;
}
public void setWatchDate(Date watchDate) {
this.watchDate = watchDate;
}
public Date getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(Date modifiedDate) {
this.modifiedDate = modifiedDate;
}
public long getMovieId() {
return movieId;
}
public void setMovieId(long movieId) {
this.movieId = movieId;
}
public MovieEntity getMovieEntity() {
return movieEntity;
}
public void setMovieEntity(MovieEntity movieEntity) {
this.movieEntity = movieEntity;
}
}
I have written a query but I am getting sql error for it
#Query(value = "select m.*, ct.ChildCount" +
"from (" +
"select mv.id, count(movie_id) as ChildCount " +
"from movie_version mv " +
"group by mv.id" +
") as ct join movie m " +
"on ct.id = m.id;",nativeQuery = true)
List<MovieEntity> getMoviesWithCount();
Error
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select mv.id, count(movie_id) as ChildCount from movie_version mv group by mv.id' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_60]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_60]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_60]
at java.lang.reflect.Constructor.newInstance(Constructor.java:422) ~[na:1.8.0_60]
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) ~[mysql-connector-java-5.1.44.jar:5.1.44]
at
Also, I am not sure if this is a right way to do it. Is there any other way I can save the count in the Transient variable. I tried using #Formuala too, but that does not give me 0 count.
Formula:
#Formula("select count(*) from movie_version mv where mv.id=id")
This is the first time I am dealing with Transient variable and I am not sure how it maps to the entity if its not persisted in the db.
However, #Formula worked for me. #Transient and #Formula cannot go together. #Formula is read only so I do not have to worry about the data being persisted.
http://outbottle.com/hibernate-populating-an-unmapped-entity-field-with-count-using-formula/

hibernate/Spring/Jpa #oneToMany cascade update

I'm trying to add in the decorator cascade = CascadeType.ALL on the field one to many of my version modele in spring in order to update every hyper parameter when i update my version.Like you can see below.
#Entity
#Table(name = "version")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Version implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Column(name = "num", nullable = false)
private Integer num;
#Column(name = "creation_date")
private ZonedDateTime creationDate;
#Column(name = "execution_date")
private ZonedDateTime executionDate;
#Column(name = "weights_uri")
private String weightsURI;
#OneToMany(mappedBy = "version", fetch = FetchType.EAGER, orphanRemoval = true)
#JsonIgnoreProperties({"version", "metricsType"})
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<ResultExecution> resultExecutions = new HashSet<>();
#OneToMany(mappedBy = "version", fetch = FetchType.EAGER, orphanRemoval = true, cascade = CascadeType.ALL)
#JsonIgnoreProperties({"version"})
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<HyperParameter> hyperParameters = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getNum() {
return num;
}
public Version num(Integer num) {
this.num = num;
return this;
}
public void setNum(Integer num) {
this.num = num;
}
public ZonedDateTime getCreationDate() {
return creationDate;
}
public Version creationDate(ZonedDateTime creationDate) {
this.creationDate = creationDate;
return this;
}
public void setCreationDate(ZonedDateTime creationDate) {
this.creationDate = creationDate;
}
public ZonedDateTime getExecutionDate() {
return executionDate;
}
public Version executionDate(ZonedDateTime executionDate) {
this.executionDate = executionDate;
return this;
}
public void setExecutionDate(ZonedDateTime executionDate) {
this.executionDate = executionDate;
}
public String getWeightsURI() {
return weightsURI;
}
public Version weightsURI(String weightsURI) {
this.weightsURI = weightsURI;
return this;
}
public void setWeightsURI(String weightsURI) {
this.weightsURI = weightsURI;
}
public Set<ResultExecution> getResultExecutions() {
return resultExecutions;
}
public Version resultExecutions(Set<ResultExecution> resultExecutions) {
this.resultExecutions = resultExecutions;
return this;
}
public Version addResultExecution(ResultExecution resultExecution) {
this.resultExecutions.add(resultExecution);
resultExecution.setVersion(this);
return this;
}
public Version removeResultExecution(ResultExecution resultExecution) {
this.resultExecutions.remove(resultExecution);
resultExecution.setVersion(null);
return this;
}
public void setResultExecutions(Set<ResultExecution> resultExecutions) {
this.resultExecutions = resultExecutions;
}
public Set<HyperParameter> getHyperParameters() {
return hyperParameters;
}
public Version hyperParameters(Set<HyperParameter> hyperParameters) {
this.hyperParameters = hyperParameters;
return this;
}
public Version addHyperParameter(HyperParameter hyperParameter) {
this.hyperParameters.add(hyperParameter);
hyperParameter.setVersion(this);
return this;
}
public Version removeHyperParameter(HyperParameter hyperParameter) {
this.hyperParameters.remove(hyperParameter);
hyperParameter.setVersion(null);
return this;
}
public void setHyperParameters(Set<HyperParameter> hyperParameters) {
this.hyperParameters = hyperParameters;
}
public Set<Data> getData() {
return data;
}
public Version data(Set<Data> data) {
this.data = data;
return this;
}
public Version addData(Data data) {
this.data.add(data);
data.getVersions().add(this);
return this;
}
public Version removeData(Data data) {
this.data.remove(data);
data.getVersions().remove(this);
return this;
}
public void setData(Set<Data> data) {
this.data = data;
}
public ModelConfiguration getModelConfiguration() {
return modelConfiguration;
}
public Version modelConfiguration(ModelConfiguration modelConfiguration) {
this.modelConfiguration = modelConfiguration;
return this;
}
public void setModelConfiguration(ModelConfiguration modelConfiguration) {
this.modelConfiguration = modelConfiguration;
}
// jhipster-needle-entity-add-getters-setters - Jhipster will add getters and setters here, do not remove
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Version version = (Version) o;
if (version.getId() == null || getId() == null) {
return false;
}
return Objects.equals(getId(), version.getId());
}
#Override
public int hashCode() {
return Objects.hashCode(getId());
}
#Override
public String toString() {
return "Version{" +
"id=" + getId() +
", num='" + getNum() + "'" +
", creationDate='" + getCreationDate() + "'" +
", executionDate='" + getExecutionDate() + "'" +
", weightsURI='" + getWeightsURI() + "'" +
"}";
}
}
My hyperParameter model looks like this :
#Entity
#Table(name = "hyper_parameter")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class HyperParameter implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Column(name = "parameter_value", nullable = false)
private String parameterValue;
#ManyToOne(optional = false)
#NotNull
#JsonIgnoreProperties({"resultExecutions", "hyperParameters", "data", "modelConfiguration"})
private Version version;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getParameterValue() {
return parameterValue;
}
public HyperParameter parameterValue(String parameterValue) {
this.parameterValue = parameterValue;
return this;
}
public void setParameterValue(String parameterValue) {
this.parameterValue = parameterValue;
}
public Version getVersion() {
return version;
}
public HyperParameter version(Version version) {
this.version = version;
return this;
}
public void setVersion(Version version) {
this.version = version;
}
public HyperParameterType getHyperParameterType() {
return hyperParameterType;
}
public HyperParameter hyperParameterType(HyperParameterType hyperParameterType) {
this.hyperParameterType = hyperParameterType;
return this;
}
public void setHyperParameterType(HyperParameterType hyperParameterType) {
this.hyperParameterType = hyperParameterType;
}
// jhipster-needle-entity-add-getters-setters - Jhipster will add getters and setters here, do not remove
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
HyperParameter hyperParameter = (HyperParameter) o;
if (hyperParameter.getId() == null || getId() == null) {
return false;
}
return Objects.equals(getId(), hyperParameter.getId());
}
#Override
public int hashCode() {
return Objects.hashCode(getId());
}
#Override
public String toString() {
return "HyperParameter{" +
"id=" + getId() +
", parameterValue='" + getParameterValue() + "'" +
"}";
}
}
I update a json and try a put with it .I change the value of the field parametervalue from 2 to 3 .
{
"id": 1,
"num": 1,
"creationDate": "2017-05-11T00:00:00+02:00",
"executionDate": null,
"weightsURI": "tests/scripts/sequential/weights/weights_le_net_5.h5py",
"resultExecutions": [
{
"id": 1,
"metricValues": "",
"executionType": "TRAIN",
"numPrediction": null
},
{
"id": 2,
"metricValues": "",
"executionType": "TRAIN",
"numPrediction": null
}
],
"hyperParameters": [
{
"id": 1,
"parameterValue": "2",
"hyperParameterType": {
"id": 1,
"name": "epochs",
"parameterType": "INTEGER",
"parameterDefaultValue": "0",
"isRequired": true
}
},
{
"id": 2,
"parameterValue": "32",
"hyperParameterType": {
"id": 2,
"name": "batch_size",
"parameterType": "INTEGER",
"parameterDefaultValue": "32",
"isRequired": true
}
}
],
"modelConfiguration": {
"id": 1,
"name": "Modele LeNet5",
"creationDate": "2017-05-11T00:00:00+02:00",
"updateDate": "2017-05-11T00:00:00+02:00",
"saveURI": "tests/scripts/sequential/models/le_net_5.json"
}
}
But when i do i got a 500 internal serveur error and stack trace like the one bellow about a null constraint violation.
<!-- What do you expect the result to be? -->
<!-- What is the actual result you get? (Please include any errors.) -->
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:526)
[1:59]
t org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:75)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:71)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
... 153 common frames omitted
Caused by: javax.validation.ConstraintViolationException: Validation failed for classes [com.saagie.picsaagie2017_frontend.domain.HyperParameter] during update time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='can not be null ', propertyPath=version, rootBeanClass=class com.saagie.picsaagie2017_frontend.domain.HyperParameter, messageTemplate='{javax.validation.constraints.NotNull.message}'}
]
How can i update my hyperParameters when i update my version whitout getting this error.
Use the #PreUpdate and #PrePersist callbacks in the HyperParameter class like so:
#PreUpdate
#PrePersist
public void setChildObjects() {
if (getVersions() != null)
{
for (Version version : getVersions())
{
version.setHyperParameters (this);
}
}
}
Refer to this for more information : http://docs.jboss.org/hibernate/core/3.3/reference/en/html/tutorial.html#tutorial-associations-usingbidir
Both solution actually work i had a second error because of what is discussed in that topic : Spring data rest one to many cascade all . I just had to add #JsonManagedReference and #JsonBackReference because i had marshalling problem on the reference of version when i tried to update my HyperParameters in cascade.
You just have validation error. You try to put interpolatedMessage with null value. Ok but first remove #NotNull annotation on this field.

Spring Data Jpa Test returns null list even after child is saved

#Test
public void testAddPlayerToGame() {
gameRepository.save(createTestGame());
Game game = gameRepository.findOne(1l);
assertTrue(game.getId() > 0);
Player p = new Player();
p.setName("test 1");
p.setGame(game);
p.setChips(5000);
assertTrue(p.getId() == null);
playerRepository.saveAndFlush(p);
assertTrue(p.getId() != null);
flushAndClear();
Game game2 = gameRepository.findOne(1l);
assertEquals(1, game2.getPlayers().size());
}
The above test fails because game2.getPlayers() returns null.
Already went through JpaRepository caches newly created object. How to refresh it? but couldn't figure out how to solve.
The method flushAndClear used in the above code is blank, as follows :
protected void flushAndClear() {
// sessionFactory.getCurrentSession().flush();
// sessionFactory.getCurrentSession().clear();
}
Any help is really appreciated.
Update
Game & Player mapping code :
#Entity
#Table(name="game")
public class Game implements Serializable {
private static final long serialVersionUID = -495064662454346171L;
private long id;
private int playersRemaining;
private Player playerInBTN;
private GameType gameType;
private String name;
private boolean isStarted;
private Set<Player> players;
private HandEntity currentHand;
private GameStructure gameStructure;
#Column(name="game_id")
#Id
#GeneratedValue(strategy=GenerationType.TABLE)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
#Column(name="players_left")
public int getPlayersRemaining() {
return playersRemaining;
}
public void setPlayersRemaining(int playersRemaining) {
this.playersRemaining = playersRemaining;
}
#OneToOne
#JoinColumn(name="btn_player_id")
public Player getPlayerInBTN(){
return playerInBTN;
}
public void setPlayerInBTN(Player playerInBTN){
this.playerInBTN = playerInBTN;
}
#Column(name="game_type")
#Enumerated(EnumType.STRING)
public GameType getGameType() {
return gameType;
}
public void setGameType(GameType gameType) {
this.gameType = gameType;
}
#OneToMany(mappedBy="game", fetch=FetchType.LAZY)
public Set<Player> getPlayers() {
return players;
}
public void setPlayers(Set<Player> players) {
this.players = players;
}
#Column(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Column(name="is_started")
public boolean isStarted() {
return isStarted;
}
public void setStarted(boolean isStarted) {
this.isStarted = isStarted;
}
#OneToOne(fetch=FetchType.EAGER)
#JoinColumn(name="current_hand_id")
public HandEntity getCurrentHand() {
return currentHand;
}
public void setCurrentHand(HandEntity currentHand) {
this.currentHand = currentHand;
}
#OneToOne(fetch=FetchType.EAGER, cascade={CascadeType.ALL})
#JoinColumn(name="game_structure_id")
public GameStructure getGameStructure() {
return gameStructure;
}
public void setGameStructure(GameStructure gameStructure) {
this.gameStructure = gameStructure;
}
}
#Entity
#Table(name="player")
public class Player implements Comparable<Player>, Serializable{
private static final long serialVersionUID = -1384636077333014255L;
private String id;
private Game game;
private String name;
private int chips;
private int gamePosition;
private int finishPosition;
private boolean sittingOut;
#JsonIgnore
#Column(name="player_id")
#Id
#GeneratedValue(generator = "system-uuid")
#GenericGenerator(name = "system-uuid", strategy = "uuid2")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#JsonIgnore
#ManyToOne
#JoinColumn(name="game_id")
public Game getGame() {
return game;
}
public void setGame(Game game) {
this.game = game;
}
#Column(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Column(name="chips")
public int getChips() {
return chips;
}
public void setChips(int chips) {
this.chips = chips;
}
#Column(name="game_position")
public int getGamePosition() {
return gamePosition;
}
public void setGamePosition(int gamePosition) {
this.gamePosition = gamePosition;
}
#Column(name="finished_place")
public int getFinishPosition() {
return finishPosition;
}
public void setFinishPosition(int finishPosition) {
this.finishPosition = finishPosition;
}
#Column(name="sitting_out")
public boolean isSittingOut() {
return sittingOut;
}
public void setSittingOut(boolean sittingOut) {
this.sittingOut = sittingOut;
}
#Override
public boolean equals(Object o){
if(o == null || !(o instanceof Player)){
return false;
}
Player p = (Player) o;
if(this.getId() == null){
return this.getName().equals(p.getName());
}
return this.getId().equals(p.getId());
}
#Override
public int hashCode(){
if(id == null){
return name.hashCode();
}
return id.hashCode();
}
#Override
#Transient
public int compareTo(Player p){
return this.getGamePosition() - p.getGamePosition();
}
}
I am using HSQL db in the testing environment. Following is the configuration :
#Configuration
#EnableJpaRepositories(basePackages = "com.nitinsurana.repos")
#EnableTransactionManagement
class TestDataConfig {
#Bean(name = "transactionManager")
#Autowired
public PlatformTransactionManager getTransactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
jpaTransactionManager.setEntityManagerFactory(entityManagerFactory);
return jpaTransactionManager;
}
#Bean
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan("com.nitinsurana.domain");
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
em.setJpaProperties(getHibernateProperties());
em.afterPropertiesSet();
return em.getObject();
}
// #Bean
// public EntityManager entityManager(HibernateEntityManagerFactory entityManagerFactory) {
// HibernateEntityManager entityManager = (HibernateEntityManager) entityManagerFactory.createEntityManager();
// entityManager.setFlushMode(FlushModeType.AUTO FlushMode.ALWAYS);
// return entityManager;
// }
private Properties getHibernateProperties() {
Properties prop = new Properties();
prop.put("hibernate.show_sql", "false");
prop.put("hibernate.hbm2ddl.auto", "create");
prop.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
return prop;
}
#Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
// .addScript("classpath:com/bank/config/sql/schema.sql")
// .addScript("classpath:com/bank/config/sql/test-data.sql")
.build();
}
}
You need to write a FlushAndClear method that works. If not game2 gets not loaded for the database but from the internal cache. And if it is not loaded then the releationship become not updated.
class TestXXX {
#PersistenceContext
private EntityManager em.
private flushAndClear() {
em.flush();
em.clear();
}
}

spring data neo4j ,i can't solve it

I use spring data neo4j,i have user.class.movie.class,rating.class,i create relationship between movie and rating,when i run the programer,i can get the rating(star,comment)but cannot get the movie's title(null)
movie.class
package com.oberon.fm.domain;
#NodeEntity
public class Movie {
#GraphId
Long nodeId;
#Indexed(indexType = IndexType.FULLTEXT, indexName = "id")
String id;
#Indexed(indexType = IndexType.FULLTEXT, indexName = "search", numeric = false)
String title;
String description;
#RelatedTo(type = "DIRECTED", direction = INCOMING)
Person director;
#RelatedTo(type = "ACTS_IN", direction = INCOMING)
Set<Person> actors;
#RelatedToVia(elementClass = Role.class, type = "ACTS_IN", direction = INCOMING)
// Iterable<Role> roles;
Set<Role> roles = new HashSet<>();
#RelatedToVia(elementClass = Rating.class, type = "RATED", direction = INCOMING)
#Fetch
Iterable<Rating> ratings;
// Set<Rating> ratings = new HashSet<>();
private String language;
private String imdbId;
private String tagline;
private Date releaseDate;
private Integer runtime;
private String homepage;
private String trailer;
private String genre;
private String studio;
private Integer version;
private Date lastModified;
private String imageUrl;
public Movie() {
}
public Long getNodeId() {
return nodeId;
}
public void setNodeId(Long nodeId) {
this.nodeId = nodeId;
}
public Movie(String id, String title) {
this.id = id;
this.title = title;
}
public Collection<Person> getActors() {
return actors;
}
public Collection<Role> getRoles() {
return IteratorUtil.asCollection(roles);
}
public int getYear() {
if (releaseDate == null)
return 0;
Calendar cal = Calendar.getInstance();
cal.setTime(releaseDate);
return cal.get(Calendar.YEAR);
}
public String getId() {
return id;
}
public String getTitle() {
return title;
}
#Override
public String toString() {
return String.format("%s (%s) [%s]", title, releaseDate, id);
}
public String getDescription() {
return description;
}
public int getStars() {
Iterable<Rating> allRatings = ratings;
if (allRatings == null)
return 0;
int stars = 0, count = 0;
for (Rating rating : allRatings) {
stars += rating.getStars();
count++;
}
return count == 0 ? 0 : stars / count;
}
public Collection<Rating> getRatings() {
Iterable<Rating> allRatings = ratings;
return allRatings == null ? Collections.<Rating> emptyList()
: IteratorUtil.asCollection(allRatings);
}
/*
* public Set<Rating> getRatings() { return ratings; }
*/
public void setRatings(Set<Rating> ratings) {
this.ratings = ratings;
}
/*
* public void addRating(Rating rating) { ratings.add(rating); }
*/
public void setTitle(String title) {
this.title = title;
}
public void setLanguage(String language) {
this.language = language;
}
public void setImdbId(String imdbId) {
this.imdbId = imdbId;
}
public void setTagline(String tagline) {
this.tagline = tagline;
}
public void setDescription(String description) {
this.description = description;
}
public void setReleaseDate(Date releaseDate) {
this.releaseDate = releaseDate;
}
public void setRuntime(Integer runtime) {
this.runtime = runtime;
}
public void setHomepage(String homepage) {
this.homepage = homepage;
}
public void setTrailer(String trailer) {
this.trailer = trailer;
}
public void setGenre(String genre) {
this.genre = genre;
}
public void setStudio(String studio) {
this.studio = studio;
}
public void setVersion(Integer version) {
this.version = version;
}
public void setLastModified(Date lastModified) {
this.lastModified = lastModified;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getLanguage() {
return language;
}
public String getImdbId() {
return imdbId;
}
public String getTagline() {
return tagline;
}
public Date getReleaseDate() {
return releaseDate;
}
public Integer getRuntime() {
return runtime;
}
public String getHomepage() {
return homepage;
}
public String getTrailer() {
return trailer;
}
public String getGenre() {
return genre;
}
public String getStudio() {
return studio;
}
public Integer getVersion() {
return version;
}
public Date getLastModified() {
return lastModified;
}
public String getImageUrl() {
return imageUrl;
}
public String getYoutubeId() {
String trailerUrl = trailer;
if (trailerUrl == null || !trailerUrl.contains("youtu"))
return null;
String[] parts = trailerUrl.split("[=/]");
int numberOfParts = parts.length;
return numberOfParts > 0 ? parts[numberOfParts - 1] : null;
}
#Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Movie movie = (Movie) o;
if (nodeId == null)
return super.equals(o);
return nodeId.equals(movie.nodeId);
}
#Override
public int hashCode() {
return nodeId != null ? nodeId.hashCode() : super.hashCode();
}
public Person getDirector() {
return director;
}
}
user.class
package com.oberon.fm.domain;
#NodeEntity
public class User {
#GraphId
Long nodeId;
public static final String SALT = "cewuiqwzie";
public static final String FRIEND = "FRIEND";
public static final String RATED = "RATED";
#Indexed(indexType = IndexType.FULLTEXT, indexName = "login")
String login;
#Indexed
String name;
String password;
public void setPassword(String password) {
this.password = password;
}
String info;
private Roles[] roles;
public User() {
}
public User(String login, String name, String password, Roles... roles) {
this.login = login;
this.name = name;
this.password = encode(password);
this.roles = roles;
}
private String encode(String password) {
return new Md5PasswordEncoder().encodePassword(password, SALT);
}
#RelatedToVia(type = RATED)
#Fetch
Iterable<Rating> ratings;
// Set<Rating> ratings = new HashSet<>();
#RelatedTo(type = RATED)
Set<Movie> favorites;
public Set<Movie> getFavorites() {
return favorites;
}
public void setFavorites(Set<Movie> favorites) {
this.favorites = favorites;
}
#RelatedTo(type = FRIEND, direction = Direction.BOTH)
#Fetch
Set<User> friends;
public void addFriend(User friend) {
this.friends.add(friend);
}
public Rating rate(Neo4jOperations template, Movie movie, int stars,
String comment) {
final Rating rating = template.createRelationshipBetween(this, movie,
Rating.class, RATED, false).rate(stars, comment);
return template.save(rating);
}
/*
* public Rating rate(Movie movie, int stars, String comment) { if (ratings
* == null) { ratings = new HashSet<>(); }
*
* Rating rating = new Rating(this, movie, stars, comment);
* ratings.add(rating); movie.addRating(rating); return rating; }
*/
public Collection<Rating> getRatings() {
return IteratorUtil.asCollection(ratings);
}
/*
* public Set<Rating> getRatings() { return ratings; }
*/
#Override
public String toString() {
return String.format("%s (%s)", name, login);
}
public String getName() {
return name;
}
public Set<User> getFriends() {
return friends;
}
public Roles[] getRole() {
return roles;
}
public String getLogin() {
return login;
}
public String getPassword() {
return password;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public void updatePassword(String old, String newPass1, String newPass2) {
if (!password.equals(encode(old)))
throw new IllegalArgumentException("Existing Password invalid");
if (!newPass1.equals(newPass2))
throw new IllegalArgumentException("New Passwords don't match");
this.password = encode(newPass1);
}
public void setName(String name) {
this.name = name;
}
public boolean isFriend(User other) {
return other != null && getFriends().contains(other);
}
public enum Roles implements GrantedAuthority {
ROLE_USER, ROLE_ADMIN;
#Override
public String getAuthority() {
return name();
}
}
#Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
User user = (User) o;
if (nodeId == null)
return super.equals(o);
return nodeId.equals(user.nodeId);
}
public Long getId() {
return nodeId;
}
#Override
public int hashCode() {
return nodeId != null ? nodeId.hashCode() : super.hashCode();
}
}
rating.class
package com.oberon.fm.domain;
#RelationshipEntity
public class Rating {
private static final int MAX_STARS = 5;
private static final int MIN_STARS = 0;
#GraphId
Long id;
#StartNode
User user;
#EndNode
Movie movie;
int stars;
String comment;
public User getUser() {
return user;
}
public Movie getMovie() {
return movie;
}
public int getStars() {
return stars;
}
public void setStars(int stars) {
this.stars = stars;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public Rating rate(int stars, String comment) {
if (stars >= MIN_STARS && stars <= MAX_STARS)
this.stars = stars;
if (comment != null && !comment.isEmpty())
this.comment = comment;
return this;
}
public Rating() {
}
public void setUser(User user) {
this.user = user;
}
public void setMovie(Movie movie) {
this.movie = movie;
}
#Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Rating rating = (Rating) o;
if (id == null)
return super.equals(o);
return id.equals(rating.id);
}
#Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}
controller
#RequestMapping(value = "/user", method = RequestMethod.GET)
public String profile(Model model, HttpServletRequest request) {
// User user=populator.getUserFromSession();
HttpSession session = request.getSession(false);
User user = (User) session.getAttribute("user");
model.addAttribute("user", user);
if (user != null) {
List<MovieRecommendation> mr = movieRepository.getRecommendations(user.getLogin());
MovieRecommendation movie = new MovieRecommendation();
Movie m = new Movie();
m.setTitle("AA");
movie.setMovie(m);
mr.add(movie);
model.addAttribute("recommendations", mr);
}
return "user/index";
}![enter image description here][4]
It only loads the movie's id by default, if you don't specify #Fetch on the movie field. But I'd rather recommend to use template.fetch(rating.movie) to load it only when you need it.

Hibernate - #IdClass #ManyToOne - Primary key is also Foreign key

Im having a little problem when Saving an Entity, (this problem only occurs when saving, im saying that because I can get execute the normal operation when findAll)
As I said, when saving the entity (repository.save(entity)), Im getting the follow exception
//org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.Integer' to required type 'net.lapasta.model.entity.Produto' for property 'produto';
//nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.Integer] to required type [net.lapasta.model.entity.Produto] for property 'produto': no matching editors or conversion strategy found
My entity is:
#Entity
#IdClass(ProdutoEstoqueRegra.PrimaryKey.class)
#Table(name = "PRODUTO_ESTOQUE_REGRA")
public class ProdutoEstoqueRegra extends BaseEntity
{
private static final long serialVersionUID = 2977957269715314234L;
public static class PrimaryKey extends BaseEntity
{
private static final long serialVersionUID = 5136771432344094321L;
private Produto produto;
private Produto produtoEstoque;
public PrimaryKey()
{
}
public PrimaryKey(Produto produto, Produto produtoEstoque)
{
this.produto = produto;
this.produtoEstoque = produtoEstoque;
}
public Produto getProduto()
{
return produto;
}
public void setProduto(Produto produto)
{
this.produto = produto;
}
public Produto getProdutoEstoque()
{
return produtoEstoque;
}
public void setProdutoEstoque(Produto produtoEstoque)
{
this.produtoEstoque = produtoEstoque;
}
#Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result += prime * result + (produto == null ? 0 : produto.getProdutoId() == null ? 0 : produto.getProdutoId().hashCode());
result += prime * result + (produtoEstoque == null ? 0 : produtoEstoque.getProdutoId() == null ? 0 : produtoEstoque.getProdutoId().hashCode());
return result;
}
#Override
public boolean equals(Object object)
{
if(this == object)
{
return true;
}
if(!(object instanceof ProdutoEstoqueRegra))
{
return false;
}
ProdutoEstoqueRegra produtoEstoqueRegra = (ProdutoEstoqueRegra) object;
if(produto == null)
{
if(produtoEstoqueRegra.getProduto() != null)
{
return false;
}
}
else if(produto.getProdutoId() == null)
{
if(produtoEstoqueRegra.getProduto().getProdutoId() != null)
{
return false;
}
}
else if(!produto.equals(produtoEstoqueRegra.getProduto()))
{
return false;
}
if(produtoEstoque == null)
{
if(produtoEstoqueRegra.getProdutoEstoque() != null)
{
return false;
}
}
else if(produtoEstoque.getProdutoId() == null)
{
if(produtoEstoqueRegra.getProdutoEstoque().getProdutoId() != null)
{
return false;
}
}
else if(!produtoEstoque.getProdutoId().equals(produtoEstoqueRegra.getProdutoEstoque().getProdutoId()))
{
return false;
}
return true;
}
}
#Id
#ManyToOne
#JoinColumn(name = "ID_PRODUTO")
private Produto produto;
#Id
#ManyToOne
#JoinColumn(name = "ID_PRODUTO_ESTOQUE")
private Produto produtoEstoque;
#Column(name = "QUANTIDADE")
private BigDecimal quantidade;
}
I just got the same problem...and i solved it by myself last :)
In your case, i assume Produto's id type is Long, u need change your PrimaryKey class like following:
public static class PrimaryKey extends BaseEntity
{
private static final long serialVersionUID = 5136771432344094321L;
private Long produto;
private Long produtoEstoque;
public PrimaryKey()
{
}
public PrimaryKey(Long produto, Long produtoEstoque)
{
this.produto = produto;
this.produtoEstoque = produtoEstoque;
}
public Long getProduto()
{
return produto;
}
public void setProduto(Long produto)
{
this.produto = produto;
}
public Long getProdutoEstoque()
{
return produtoEstoque;
}
public void setProdutoEstoque(Long produtoEstoque)
{
this.produtoEstoque = produtoEstoque;
}
//...
}

Resources