Does Neo4j OGM work well with interfaces? - java

I've developed two sets of classes - the first one are just classes, whereas in the second set, the classes derive from interfaces. Both the sets of classes mimic each other. The repositories for them are also similar. However, the repository works well for the first set of classes (nodes and relationships). For the second set of classes though, the repository is able to insert records, but the findAll method fails and doesn't return me any records.
Here's the first set of classes with the repository -
public abstract class Entity {
#GraphId
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || id == null || getClass() != o.getClass()) return false;
Entity entity = (Entity) o;
if (!id.equals(entity.id)) return false;
return true;
}
#Override
public int hashCode() {
return (id == null) ? -1 : id.hashCode();
}
}
public abstract class GenericRepository<T> implements IGenericRepository<T> {
private static final int DEPTH_LIST = 1;
private static final int DEPTH_ENTITY = 2;
private Session session;
public GenericRepository(String url, String username, String password) {
super();
session = Neo4jSessionFactory.getInstance().getNeo4jSession(url, username, password);
}
public Iterable<T> findAll() {
return session.loadAll(getEntityType(), DEPTH_LIST);
}
public T findOne(Long id) {
return session.load(getEntityType(), id, DEPTH_ENTITY);
}
public void delete(T entity) {
session.delete(session.load(getEntityType(), ((Entity) entity).getId()));
}
public T createOrUpdate(T entity) {
session.save(entity, DEPTH_ENTITY);
return findOne(((Entity) entity).getId());
}
public abstract Class<T> getEntityType();
}
#RelationshipEntity(type="MY_ROLE")
public class ARole extends Entity {
#Property
private String title;
#StartNode
private HomoSapiens start;
#EndNode
private HomoSapiens end;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public HomoSapiens getStart() {
return start;
}
public void setStart(HomoSapiens start) {
this.start = start;
}
public HomoSapiens getEnd() {
return end;
}
public void setEnd(HomoSapiens end) {
this.end = end;
}
public ARole() {}
public ARole(String title) {
this.title = title;
}
}
#NodeEntity
public class HomoSapiens extends Entity {
private String name;
#Relationship(type = "MY_ROLE", direction = Relationship.INCOMING)
private ARole aRole;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ARole getaRole() {
return aRole;
}
public void setaRole(ARole aRole) {
this.aRole = aRole;
}
public HomoSapiens() {}
public HomoSapiens(String name) {
this.name = name;
}
}
public class ARoleDao extends GenericRepository<ARole> implements IARoleDao {
public ARoleDao(String url, String username, String password) {
super(url, username, password);
}
#Override
public Class<ARole> getEntityType() {
return ARole.class;
}
}
Here's the second set of classes -
public interface IARole {
String getTitle();
void setTitle(String title);
IHomoSapiens getStart();
void setStart(IHomoSapiens start);
IHomoSapiens getEnd();
void setEnd(IHomoSapiens end);
}
public interface IHomoSapiens {
String getName();
void setName(String name);
IARole getARole();
void setARole(IARole aRole);
}
#RelationshipEntity(type="MY_DERIVED_ROLE")
public class DerivedARole extends Entity implements IARole {
#Property
private String title;
#StartNode
private IHomoSapiens start;
#EndNode
private IHomoSapiens end;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public IHomoSapiens getStart() {
return start;
}
public void setStart(IHomoSapiens start) {
this.start = start;
}
public IHomoSapiens getEnd() {
return end;
}
public void setEnd(IHomoSapiens end) {
this.end = end;
}
public DerivedARole() {}
public DerivedARole(String title) {
this.title = title;
}
}
#NodeEntity
public class DerivedHomoSapiens extends Entity implements IHomoSapiens {
private String name;
#Relationship(type = "MY_DERIVED_ROLE", direction = Relationship.INCOMING)
private IARole aRole;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public IARole getARole() {
return aRole;
}
public void setARole(IARole aRole) {
this.aRole = aRole;
}
public DerivedHomoSapiens() {}
public DerivedHomoSapiens(String name) {
this.name = name;
}
}
public class DerivedARoleDao extends GenericRepository<DerivedARole> {
public DerivedARoleDao(String url, String username, String password) {
super(url, username, password);
}
#Override
public Class<DerivedARole> getEntityType() {
return DerivedARole.class;
}
}
public class DerivedARoleDaoSpecs {
private DerivedARoleDao derivedARoleDao;
#Before
public void setUp() throws Exception {
derivedARoleDao = new DerivedARoleDao(DomainHelper.NEO_URL, DomainHelper.NEO_USERNAME,
DomainHelper.NEO_PASSWORD);
}
public void should_insert_data() {
IHomoSapiens start = new DerivedHomoSapiens("d-start");
IHomoSapiens end = new DerivedHomoSapiens("d-end");
IARole aRole = new DerivedARole("parent");
start.setARole(aRole);
end.setARole(aRole);
aRole.setStart(start);
aRole.setEnd(end);
IARole created = derivedARoleDao.createOrUpdate((DerivedARole)aRole);
assertThat(created, is(notNullValue()));
}
public void should_find_all() {
Iterable<DerivedARole> derivedARoles = derivedARoleDao.findAll();
assertThat(derivedARoles, is(notNullValue()));
assertThat(Iterables.isEmpty(derivedARoles), is(false));
assertTrue(Iterables.size(derivedARoles) > 0);
System.out.println(Iterables.size(derivedARoles));
}
#Test
public void should_do_crud() {
// should_insert_data();
should_find_all();
// should_find_by_id();
}
}
Am I missing something here? Or does the Neo4j OGM works well with classes (not implementing interfaces)?
The entire source code is at - https://github.com/mmwaikar/java-neo-ogm-ex (in case, it helps).
Thanks,
Manoj.

This should be fixed in 1.1.3
Till that is released, please try your code example with 1.1.3-SNAPSHOT.
You'll need to include
<repository>
<id>neo4j-snapshots</id>
<url>http://m2.neo4j.org/content/repositories/snapshots</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>

Related

Stack overflow error while invoking toString method

this is my code but when I execute the program I get many errors and I don't know why. May anyone help me?
RegisteredUser.java
public class RegisteredUser {
private String nickname;
ArrayList<ReviewDAO> reviews;
public RegisteredUser(String nickname) {
this.nickname = nickname;
reviews = new ArrayList<>();
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public void addReview(ReviewDAO review) {
if (!this.reviews.contains(review)) {
this.reviews.add(review);
review.addRegisteredUser(this);
}
}
#Override
public String toString() {
return "RegisteredUser{" +
"nickname='" + nickname + '\'' +
", reviews=" + reviews +
'}';
}
}
ReviewDAO.java
public abstract class ReviewDAO {
RegisteredUser registeredUser;
public abstract boolean write(Review review);
public void addRegisteredUser(RegisteredUser registeredUser) {
this.registeredUser = registeredUser;
}
#Override
public String toString() {
return "ReviewDAO{" +
"registeredUser=" + registeredUser +
'}';
}
}
Review.java
public class Review {
private String title;
private String description;
private int rank;
private boolean isAnonymous;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getRank() {
return rank;
}
public void setRank(int rank) {
this.rank = rank;
}
public boolean isAnonymous() {
return isAnonymous;
}
public void setAnonymous(boolean anonymous) {
isAnonymous = anonymous;
}
}
ReviewDAO_MongoDB.java
public class ReviewDAO_MongoDB extends ReviewDAO {
#Override
public boolean write(Review review) {
return false;
// todo
}
}
ReviewDAO_Factory.java
public class ReviewDAO_Factory {
public ReviewDAO getReviewDAO(String technology) throws ExecutionControl.NotImplementedException {
if (technology.equals("mongodb"))
return new ReviewDAO_MongoDB();
else
throw new ExecutionControl.NotImplementedException("");
}
}
BusinessLogic.java
public class BusinessLogic {
public static void main(String[] args) throws ExecutionControl.NotImplementedException {
ReviewDAO_Factory reviewDAO_factory = new ReviewDAO_Factory();
RegisteredUser registeredUser = new RegisteredUser("Alessandro");
registeredUser.addReview(reviewDAO_factory.getReviewDAO("mongodb"));
System.out.println(registeredUser.toString());
}
}
I am getting
Exception in thread "main" java.lang.StackOverflowError
at RegisteredUser.toString(RegisteredUser.java:33)
at java.base/java.lang.String.valueOf(String.java:2951)
at ReviewDAO.toString(ReviewDAO.java:15)
...
Process finished with exit code 1
errors
First of all, the design looks faulty. You should never mix POJOs with DAOs. DAOs are "data access object" classes which deals with CRUD operations on the POJOs. Here you have 2 POJOs - Review and RegisteredUser. It's the responsibility of ReviewDAO to perform CRUD operations on managed/unmanaged instances (or entities) of Review.
And for RegisteredUser also you need another POJO probably (in your actual code).
Secondly, I see you are calling List contains method to check if the user already has given that review, yet you have not implemented "equals" and "hashCode" in the ReviewDAO.
public void addReview(ReviewDAO review) {
if (!this.reviews.contains(review)) {
this.reviews.add(review);
review.addRegisteredUser(this);
}
}
I have made few tweaks. Please check if it satisfies your need:
RegisteredUser class (Have used hashset cause "contains" search will be faster)
public class RegisteredUser {
private String nickname;
private Set<Review> reviews;
public RegisteredUser(String nickname) {
this.nickname = nickname;
reviews = new HashSet<>();
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public void addReview(Review review) {
if (!this.reviews.contains(review)) {
this.reviews.add(review);
//review.addRegisteredUser(this);
}
}
#Override
public String toString() {
return "RegisteredUser{" +
"nickname='" + nickname + '\'' +
", reviews=" + reviews +
'}';
}
}
ReviewDAO class:
public abstract class ReviewDAO {
private RegisteredUser registeredUser;
public abstract boolean write(Review review);
public void addRegisteredUser(RegisteredUser registeredUser) {
this.registeredUser = registeredUser;
}
}
Review class:
public class Review {
private String title;
private String description;
private int rank;
private boolean isAnonymous;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getRank() {
return rank;
}
public void setRank(int rank) {
this.rank = rank;
}
public boolean isAnonymous() {
return isAnonymous;
}
public void setAnonymous(boolean anonymous) {
isAnonymous = anonymous;
}
#Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Review review = (Review) o;
return Objects.equals(title, review.title);
}
#Override
public int hashCode() {
return Objects.hash(title);
}
}
BusinessLogic class
public class BusinessLogic {
public static void main(String[] args) throws ExecutionControl.NotImplementedException {
ReviewDAO_Factory reviewDAO_factory = new ReviewDAO_Factory();
RegisteredUser registeredUser = new RegisteredUser("Alessandro");
Review review = new Review();
review.setTitle("some review");
review.setDescription("some desc");
registeredUser.addReview(review);
ReviewDAO reviewDAO = reviewDAO_factory.getReviewDAO("mongodb");
reviewDAO.addRegisteredUser(registeredUser);
System.out.println(registeredUser.toString());
}
}

Springboot Jpa updating records instead of inserting

I'm doing the below query to find records that are in a temp table and dont exist in master then insert the results to the master table
#Query(value = "select b from InboundTemp b where b.transactionId NOT IN (SELECT p2.transactionId FROM Inbound p2)")
ArrayList<InboundTemp> findMissing();
However if I pass a single result object to the JpaRepository save method (To update the master table)it does an update instead of an insert.
what would I be doing wrong?
import java.io.Serializable;
import javax.persistence.*;
import java.util.Date;
#Entity
#Table(name="inbound_postpay_temp")
#NamedQuery(name="InboundPostpayTemp.findAll", query="SELECT i FROM InboundPostpayTemp i")
public class InboundPostpayTemp implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
private int id;
#Column(name="bill_ref_no")
private String billRefNo;
#Column(name="business_shortcode")
private String businessShortcode;
private byte clicked;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="created_at")
private Date createdAt;
private String kpresponse;
private String KPtransaction_id;
#Column(name="mpesa_sender")
private String mpesaSender;
private String msisdn;
#Column(name="Network")
private String network;
#Column(name="org_account_balance")
private float orgAccountBalance;
private String status;
#Column(name="transaction_amount")
private float transactionAmount;
#Column(name="transaction_id")
private String transactionId;
#Column(name="transaction_time")
private String transactionTime;
#Column(name="transaction_type")
private String transactionType;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="updated_at")
private Date updatedAt;
public InboundPostpayTemp() {
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getBillRefNo() {
return this.billRefNo;
}
public void setBillRefNo(String billRefNo) {
this.billRefNo = billRefNo;
}
public String getBusinessShortcode() {
return this.businessShortcode;
}
public void setBusinessShortcode(String businessShortcode) {
this.businessShortcode = businessShortcode;
}
public byte getClicked() {
return this.clicked;
}
public void setClicked(byte clicked) {
this.clicked = clicked;
}
public Date getCreatedAt() {
return this.createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public String getKpresponse() {
return this.kpresponse;
}
public void setKpresponse(String kpresponse) {
this.kpresponse = kpresponse;
}
public String getKPtransaction_id() {
return this.KPtransaction_id;
}
public void setKPtransaction_id(String KPtransaction_id) {
this.KPtransaction_id = KPtransaction_id;
}
public String getMpesaSender() {
return this.mpesaSender;
}
public void setMpesaSender(String mpesaSender) {
this.mpesaSender = mpesaSender;
}
public String getMsisdn() {
return this.msisdn;
}
public void setMsisdn(String msisdn) {
this.msisdn = msisdn;
}
public String getNetwork() {
return this.network;
}
public void setNetwork(String network) {
this.network = network;
}
public float getOrgAccountBalance() {
return this.orgAccountBalance;
}
public void setOrgAccountBalance(float orgAccountBalance) {
this.orgAccountBalance = orgAccountBalance;
}
public String getStatus() {
return this.status;
}
public void setStatus(String status) {
this.status = status;
}
public float getTransactionAmount() {
return this.transactionAmount;
}
public void setTransactionAmount(float transactionAmount) {
this.transactionAmount = transactionAmount;
}
public String getTransactionId() {
return this.transactionId;
}
public void setTransactionId(String transactionId) {
this.transactionId = transactionId;
}
public String getTransactionTime() {
return this.transactionTime;
}
public void setTransactionTime(String transactionTime) {
this.transactionTime = transactionTime;
}
public String getTransactionType() {
return this.transactionType;
}
public void setTransactionType(String transactionType) {
this.transactionType = transactionType;
}
public Date getUpdatedAt() {
return this.updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
}
The master class is the same
Below is the method that is persisting to dB
missing = temprepo.findMissing();
for (InboundPostpayTemp inboundPostpayTemp2 : missing) {
postpaytransaction.setBillRefNo(inboundPostpayTemp2.getBillRefNo());
postpaytransaction.setBusinessShortcode("");
// postpaytransaction.setClicked("0".t);
postpaytransaction
.setCreatedAt(new java.sql.Timestamp(inboundPostpayTemp2.getCreatedAt().getTime()));
postpaytransaction.setMpesaSender(inboundPostpayTemp2.getMpesaSender());
postpaytransaction.setMsisdn(inboundPostpayTemp2.getMsisdn());
postpaytransaction.setTransactionAmount(inboundPostpayTemp2.getTransactionAmount());
postpaytransaction.setTransactionId(inboundPostpayTemp2.getTransactionId());
postpaytransaction.setTransactionType("Paybill-Repost");
postpaytransaction.setStatus("CONFIRMED");
postpaytransaction.setTransactionTime(inboundPostpayTemp2.getTransactionTime());
//postpaytransactionx.add(postpaytransaction);
inboundpostpayrepo.save(postpaytransaction);
}
The only reason why JPA does an update instead of insert is that the Primary Key already exists in your persistence layer or your table. So kindly check or post your source code in order to review it and find what is wrong (if the issue is not in your data).
Now that you have updated the question with the source code, your bug is probably on the instantiation of the postpaytransaction object.
try to insert into your loop before everything else
postpaytransaction = new PostPayTransaction ()
I had the exactly same issue. My point was that the SpringBoot was automatically recreating the DB on startup, incorrectly creating the identity column in the table.
Look for spring.jpa.hibernate.ddl-auto.

How to use jdbctemplate and row mapper to create object with a list of objects?

I was wondering how to use jdbctemplate and RowMapper to create object with a list of objects?
Below are the three objects that I need to get mapped based on data from the db.
public class UserDTO {
private String userID;
private String email;
private List<RooftopDTO> rooftops;
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public List<RooftopDTO> getRooftops() {
return rooftops;
}
public void setRooftops(List<RooftopDTO> rooftops) {
this.rooftops = rooftops;
}
}
public class RooftopDTO {
private String dealerID;
private String name;
private String address;
private List<VenueDTO> venues;
public String getDealerID() {
return dealerID;
}
public void setDealerID(String dealerID) {
this.dealerID = dealerID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<VenueDTO> getVenues() {
return venues;
}
public void setVenues(List<VenueDTO> venues) {
this.venues = venues;
}
}
public class VenueDTO {
private int integrationID;
private String rooftopID;
public int getIntegrationID() {
return integrationID;
}
public void setIntegrationID(int integrationID) {
this.integrationID = integrationID;
}
public String getRooftopID() {
return rooftopID;
}
public void setRooftopID(String rooftopID) {
this.rooftopID = rooftopID;
}
}
As you can see, I need to create lists of objects within each object. This is what I have so far in my MapperClass, but I can't figure out what else to do..
public class UserDTOMapper implements RowMapper<UserDTO> {
#Override
public UserDTO mapRow(ResultSet rs, int rowNum) throws SQLException {
UserDTO userDTO = new UserDTO();
RooftopDTO rooftops = new RooftopDTO();
VenueDTO venues = new VenueDTO();
ArrayList<VenueDTO> venueList = new ArrayList<>();
ArrayList<RooftopDTO> rooftopList = new ArrayList<>();
userDTO.setUserID(rs.getString("user_id"));
userDTO.setEmail(rs.getString("email"));
rooftops.setDealerID(rs.getString("dealer_id"));
rooftops.setAddress(rs.getString("addr_1"));
rooftops.setName(rs.getString("dealer_nm"));
venues.setIntegrationID(rs.getInt("integration_id"));
venues.setRooftopID("act_org_id");
}
}
Can someone help me finish this mapRow method?

map 2 collection types using modelmapper

I am developing and spring application and for object mapping I am using ModelMapper library.
I am able to map basic class mapping but when I am trying to map 2 collection elements, source is set of enumeration with additional property like name and description and destination is pojo having id, name and description.
I have tried typemap and converters in mapping profile but I am getting exception of mapper.
And the source class is from other application(whose dependency have been added in pom.xml). I also don't want source type as an argument in setter of destination.
Ex.
SOURCE:
public class VType{
private int id;
private String name;
private String description;
}
public class VDTO{
private Set<VType> vTypes;
public Set<VType> getVTypes(){
return this.vTypes;
}
public void setVType() { //here I don't want to pass source type as an argument
//code stuff that I don't know what to do here
}
}
SOURCE ENUM:
public enum SourceVType{
V1(1, "Name1", "Desc1");
V2(2, "Name2", "Desc2");
private Integer id;
private String name;
private String description;
SourceVType(Integer id, String name, String description) {
this.id = id;
this.name = name;
this.description = description;
}
//getter-setter
}
Have you tried converter feature of modelmapper. You can use typemap converter to achieve this requirement.
#RunWith(JUnit4.class)
public class TempTest {
#Test
public void TestThis(){
final ModelMapper mapper = new ModelMapper();
mapper.addMappings(new PropertyMap<SrcClass, DestClass>() {
#Override
protected void configure() {
this.map().setId(this.source.getId());
this.map().setName(this.source.getName());
mapper.createTypeMap(TypeEnum.class, TypeClass.class).setConverter(
new Converter<TypeEnum, TypeClass>() {
#Override
public TypeClass convert(MappingContext<TypeEnum, TypeClass> mappingContext) {
if (mappingContext.getSource() == null) {
return null;
}
TypeEnum typeEnum = mappingContext.getSource();
TypeClass typeClass = new TypeClass();
typeClass.setId(typeEnum.getId());
typeClass.setName(typeEnum.getName());
return typeClass;
}
});
}
});
SrcClass srcObj = new SrcClass();
srcObj.setId(1);
srcObj.setName("name");
srcObj.setTypes(new HashSet<>(Arrays.asList(TypeEnum.TYPE1, TypeEnum.TYPE2)));
DestClass dstObj = mapper.map(srcObj, DestClass.class);
Assert.assertEquals(srcObj.getId(), dstObj.getId());
Assert.assertEquals(srcObj.getName(), dstObj.getName());
Assert.assertEquals(srcObj.getTypes().size(), dstObj.getTypes().size());
for(TypeClass c : dstObj.getTypes()) {
TypeEnum e = TypeEnum.getById(c.getId());
Assert.assertNotNull(e);
Assert.assertTrue(srcObj.getTypes().contains(e));
}
}
public static <Source, Result> Set<Result> convertAll(Set<Source> source, Function<Source, Result> projection)
{
Set<Result> results = new HashSet<>();
if(source == null) return results;
for (Source element : source)
{
results.add(projection.apply(element));
}
return results;
}
public static class SrcClass{
private Integer id;
private String name;
private Set<TypeEnum> types;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<TypeEnum> getTypes() {
return types;
}
public void setTypes(Set<TypeEnum> types) {
this.types = types;
}
}
public static class DestClass{
private Integer id;
private String name;
private Set<TypeClass> types;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<TypeClass> getTypes() {
return types;
}
public void setTypes(Set<TypeClass> types) {
this.types = types;
}
}
public static enum TypeEnum{
TYPE1(1, "Type 1")
, TYPE2(2, "Type 2")
, TYPE3(3, "Type 3")
, TYPE4(4, "Type 4");
private Integer id;
private String name;
TypeEnum(Integer id, String name) {
this.id = id;
this.name = name;
}
private static final Map<Integer, TypeEnum> byId = new HashMap<>();
private static final Map<String, TypeEnum> byName = new HashMap<>();
static {
for (TypeEnum e : TypeEnum.values()) {
if (byId.put(e.getId(), e) != null) {
throw new IllegalArgumentException("duplicate id: " + e.getId());
}
if (byName.put(e.getName(), e) != null) {
throw new IllegalArgumentException("duplicate name: " + e.getName());
}
}
}
public Integer getId() {
return this.id;
}
public String getName() { return this.name; }
public static TypeEnum getById(Integer id) {
return byId.get(id);
}
public static TypeEnum getByName(String name) {
return byName.get(name);
}
}
public static class TypeClass{
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}

hibernate session.persist(object) create more rows in database

Helo,
I have method
public void createContest(Contest c) {
session.beginTransaction();
session.persist(c);
session.getTransaction().commit();
logger.info("Contest saved successfully!");
}
I call it in one place with one object but this method save the object Contest to the database 4x. What could be the problem?
Here is Contest class:
#Entity
#Table(name = "Contest")
public class Contest implements java.io.Serializable {
#Id
#Column(name="CONTEST_ID", unique = true, nullable = false, precision = 5, scale = 0)
#GeneratedValue
private int id;
#Column(name="NAME")
private String name;
#Column(name="DATE_OF_EVENT")
private Date dateOfEvent;
#Column(name="REG_OPEN")
private Date regOpen;
#Column(name="REG_CLOSE")
private Date regClose;
#Column(name="REG_RESTRICTION")
private Boolean regRestriction;
#Column(name="CAPACITY")
private int capacity;
#OneToMany(mappedBy="upperContest")
private List<Contest> precontests;
#ManyToOne(cascade={CascadeType.ALL})
#JoinColumn(name="UPPER_CONTEST_ID")
private Contest upperContest;
#ManyToMany(cascade = {CascadeType.ALL})
#JoinTable(name="MANAGING",
joinColumns={#JoinColumn(name="CONTEST_ID")},
inverseJoinColumns={#JoinColumn(name="PERSON_ID")})
private List<Person> managers;
#OneToMany(mappedBy="contest")
private List<Team> teams;
public Contest(String name, Date dateOfEvent, Date regOpen,
Date regClose, Boolean regRestriction) {
this.name = name;
this.dateOfEvent = dateOfEvent;
this.regOpen = regOpen;
this.regClose = regClose;
this.regRestriction = regRestriction;
this.precontests = new ArrayList<Contest>();
this.managers = new ArrayList<Person>();
this.teams = new ArrayList<Team>();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDateOfEvent() {
return dateOfEvent;
}
public void setDateOfEvent(Date dateOfEvent) {
this.dateOfEvent = dateOfEvent;
}
public Date getRegOpen() {
return regOpen;
}
public void setRegOpen(Date regOpen) {
this.regOpen = regOpen;
}
public Date getRegClose() {
return regClose;
}
public void setRegClose(Date regClose) {
this.regClose = regClose;
}
public Boolean getRegRestriction() {
return regRestriction;
}
public void setRegRestriction(Boolean regRestriction) {
this.regRestriction = regRestriction;
}
public int getCapacity() {
return capacity;
}
public void setCapacity(int capacity) {
this.capacity = capacity;
}
public Contest getUpperContest() {
return upperContest;
}
public void setUpperContest(Contest c) {
this.upperContest = c;
}
public List<Contest> getPrecontests() {
return precontests;
}
public void addPrecontest(Contest e) {
this.precontests.add(e);
}
public void addManager(Person p){
this.managers.add(p);
}
public void addTeam(Team t){
this.teams.add(t);
}
public List<Person> getManagers(){
return managers;
}
}
And now I have to add some text because of restrictions of stackoverflow. Such Cool. Very wow.
You haven't posted the code where you instantiate Contest and populate its fields, but upperContest is probably the cause. You have CascadeType.ALL on the mapping, so you probably are persisting one contest which has a upper contest, thus actually persisting two instances because of cascade setting. Can't know for sure without that code.

Categories