Objectify 4 - Fields are not persisted - java

Using Objectify 4, name and price fields are not persisted when I save a MenuItem object.
Only Key, WriteOps and ID/Name are persisted in the debugging datastore.
#Entity
public class MenuItem extends BaseEntity {
private String name;
private double price;
public MenuItem() {
}
public MenuItem(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
Where BaseEntity is:
public abstract class BaseEntity implements Dto {
private static final long serialVersionUID = 8400346403708831769L;
#Id
protected Long id;
protected BaseEntity() {
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
BaseEntity other = (BaseEntity) obj;
if (id == null) {
if (other.id != null) {
return false;
}
} else if (!id.equals(other.id)) {
return false;
}
return true;
}
public Long getId() {
return id;
}
public void setId(#Nullable Long id) {
this.id = id;
}
public boolean isSaved() {
return (id != null);
}
}
and Dto is:
public interface Dto extends Serializable {
}
Any ideas? Thanks!

As stated on the Objectify mailing list, it may just be your viewing of the datastore that is missing this information.
Can you show some test code to save this data then retrieve it and print out the results rather than using the datastore viewer? I'd expect:
MenuItem toSave = new MenuItem("test", 6.3);
toSave.setId(1);
ofy().save().entity(toSave).now();
ofy().clear(); //Make sure we're not just looking at the current session.
MenuItem loaded = ofy().load().type(MenuItem.class).id(1).get();
assertEquals(loaded.getName(), "test");
assertEquals(loaded.getPrice(), 6.3);

Related

JPA Spring CrudRepository TransientObjectException

I want to manage Persons, Teams and their Membership with Spring Data JPA.
The following test (whenAddingANewTeamTroughPerson)
passes when I use entityManager.persist(alex);
throws an exception if I use personRepository.save(alex);
Why? In the latter case I get the following exception:
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: hello.data.model.Person; nested exception is java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: hello.data.model.Person
It behaves as CASCADE is not set properely. But it must be correct, since it works with the entityManager.
PersonRepositoryTest:
#RunWith(SpringRunner.class)
#DataJpaTest
public class PersonRepositoryTest {
#Autowired
private TestEntityManager entityManager;
#Autowired
private PersonRepository personRepository;
#Autowired
private TeamRepository teamRepository;
#Test
public void whenFindOne_thenReturnPerson() {
// given
Person alex = new Person("alex");
entityManager.persist(alex);
entityManager.flush();
// when
Person found = personRepository.findOne(alex.getId());
// then
assertThat(found.getName(), equalToIgnoringWhiteSpace(alex.getName()));
}
#Test
public void whenAddingANewTeamTroughPerson_thenNoException() {
// given
Person alex = new Person("alex");
Team t = new Team("team");
alex.addTeam(t, "integrationTest", new Date());
personRepository.save(alex);
//entityManager.persist(alex);
// when
Person found = personRepository.findOne(alex.getId());
// then
assertThat(found.getTeams().size(), is(1));
}
}
PersonRepository:
public interface PersonRepository extends CrudRepository<Person, Integer> {}
Person:
#Entity
public class Person {
private static final Logger LOG = LoggerFactory.getLogger(Person.class);
private final IntegerProperty id = new SimpleIntegerProperty(this, "id");
private final StringProperty name = new SimpleStringProperty(this, "name");
private Set<PersonTeam> personTeams = new LinkedHashSet<>();
private ListProperty<Team> teams = new SimpleListProperty<>(this, "teams", FXCollections.observableArrayList());
public Person(String s) {
this.name.set(s);
}
public Person() {}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
public Integer getId() {
return id.get();
}
public void setId(Integer id) {
this.id.set(id);
}
public IntegerProperty idProperty() {
return id;
}
#Basic
#Column(name = "name")
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
public StringProperty nameProperty() {
return name;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.person", cascade=CascadeType.ALL, orphanRemoval = true)
public Set<PersonTeam> getPersonTeams() {
return personTeams;
}
public void setPersonTeams(Set<PersonTeam> personTeams) {
this.personTeams = personTeams;
teams.setAll(personTeams.stream().map(PersonTeam::getTeam).collect(Collectors.toList()));
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (getId() != null ? !getId().equals(person.getId()) : person.getId() != null) return false;
if (getName() != null ? !getName().equals(person.getName()) : person.getName() != null) return false;
return true;
}
#Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (getName() != null ? getName().hashCode() : 0);
return result;
}
/**
* Returns an Observable List that must remain unchanged.
* Unfortunately there is no RO Observable List Interface to refer to.
*/
#Transient
public ObservableList<Team> getTeams() {
return teams.get();
}
#Transient
public ReadOnlyListProperty<Team> teamsProperty() {
return teams;
}
public void addTeam(Team team, String createdBy, Date createdDate) {
final PersonTeam personTeam = new PersonTeam(this, team);
personTeam.setCreatedBy(createdBy);
personTeam.setCreatedDate(createdDate);
if( !personTeams.add(personTeam) ) {
LOG.error("Failed to add personTeam " + personTeam + " to collection personTeams " + personTeams);
}
if( !team.getPersonTeams().add( personTeam ) ) {
LOG.error("Failed to add personTeam " + personTeam + " to collection team.getPersonTeams " + team.getPersonTeams());
}
teams.setAll(personTeams.stream().map(PersonTeam::getTeam).collect(Collectors.toList()));
}
public void removeTeam(Team team) {
PersonTeam personTeam = new PersonTeam( this, team );
team.getPersonTeams().remove( personTeam );
personTeams.removeIf( pt -> pt.getTeam() == team );
personTeam.setPerson( null );
personTeam.setTeam( null );
teams.setAll(personTeams.stream().map(PersonTeam::getTeam).collect(Collectors.toList()));
}
/*
The method is not intended to be used in the GUI.
Use the {#link GUIRepresentable} interface instead.
*/
#Override
public String toString() {
return name.getValue();
}
}
PersonTeam:
#Entity
#Table(name = "person_team")
#AssociationOverrides({
#AssociationOverride(name = "pk.person",
joinColumns = #JoinColumn(name = "PERSON_ID")),
#AssociationOverride(name = "pk.team",
joinColumns = #JoinColumn(name = "TEAM_ID")) })
public class PersonTeam implements java.io.Serializable {
private PersonTeamPk pk = new PersonTeamPk();
private Date createdDate;
private String createdBy;
public PersonTeam() {
}
public PersonTeam(Person person, Team team) {
this.pk.setPerson(person);
this.pk.setTeam(team);
}
#EmbeddedId
public PersonTeamPk getPk() {
return pk;
}
public void setPk(PersonTeamPk pk) {
this.pk = pk;
}
#Transient
public Person getPerson() {
return getPk().getPerson();
}
public void setPerson(Person person) {
getPk().setPerson(person);
}
#Transient
public Team getTeam() {
return getPk().getTeam();
}
public void setTeam(Team team) {
getPk().setTeam(team);
}
#Temporal(TemporalType.DATE)
#Column(name = "CREATED_DATE", nullable = false, length = 10)
public Date getCreatedDate() {
return this.createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
#Column(name = "CREATED_BY", nullable = false, length = 10)
public String getCreatedBy() {
return this.createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
PersonTeam that = (PersonTeam) o;
if (getPk() != null ? !getPk().equals(that.getPk())
: that.getPk() != null)
return false;
return true;
}
public int hashCode() {
return (getPk() != null ? getPk().hashCode() : 0);
}
}
PersonTeamPk:
#Embeddable
public class PersonTeamPk implements java.io.Serializable {
private Person person;
private Team team;
#ManyToOne(cascade = CascadeType.ALL)
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
#ManyToOne(cascade = CascadeType.ALL)
public Team getTeam() {
return team;
}
public void setTeam(Team team) {
this.team = team;
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PersonTeamPk that = (PersonTeamPk) o;
if (person != null ? !person.equals(that.person) : that.person != null) return false;
if (team != null ? !team.equals(that.team) : that.team != null)
return false;
return true;
}
public int hashCode() {
int result;
result = (person != null ? person.hashCode() : 0);
result = 31 * result + (team != null ? team.hashCode() : 0);
return result;
}
}
Team:
#Entity
public class Team implements Serializable, Comparable<Team> {
private final IntegerProperty id = new SimpleIntegerProperty(this, "id");
private final StringProperty name = new SimpleStringProperty(this, "name");
private Set<PersonTeam> personTeams = new LinkedHashSet<>();
public Team(String s) {
this.name.set(s);
}
public Team() {}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
public Integer getId() {
return id.get();
}
public void setId(Integer id) {
this.id.set(id);
}
public IntegerProperty idProperty() {
return id;
}
#Basic
#Column(name = "name")
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
public StringProperty nameProperty() {
return name;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.team", orphanRemoval = true, cascade = CascadeType.ALL)
public Set<PersonTeam> getPersonTeams() {
return personTeams;
}
public void setPersonTeams(Set<PersonTeam> personTeams) {
this.personTeams = personTeams;
}
public static Callback<Team, Observable[]> extractor() {
return (Team p) -> new Observable[]{p.nameProperty()};
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Team team = (Team) o;
if (getId() != null ? !getId().equals(team.getId()) : team.getId() != null) return false;
if (getName() != null ? !getName().equals(team.getName()) : team.getName() != null) return false;
return true;
}
#Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (getName() != null ? getName().hashCode() : 0);
return result;
}
#Override
public String toString() {
return name.getValue();
}
#Override
public int compareTo(Team o) {
return Integer.compare(getId(), o.getId());
}
}

Spring data Cassandra #Indexed annotation

I was working on Spring data Cassandra While creating an entity I am giving the required annotations for fields but when I am giving #Indexed annotation for creating an secondary index in the Schema and I am not able to query on the indexed attribute with out giving Allow Filtering.Could some one please tell me how to create a Secondary Index using Spring data annotations in Cassandra
This is the sample cod that I am using creating a Sprind data Cassandra Entity.#Indexed annotation not creating a secondary index in Cassandra database
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import org.springframework.data.cassandra.mapping.CassandraType;
import org.springframework.data.cassandra.mapping.Column;
import org.springframework.data.cassandra.mapping.Indexed;
import org.springframework.data.cassandra.mapping.PrimaryKey;
import org.springframework.data.cassandra.mapping.Table;
import org.springframework.data.cassandra.mapping.UserDefinedType;
import com.datastax.driver.core.DataType;
import com.suntecgroup.xelerate.platform.demo.config.SpringContainer;
import com.suntecgroup.xelerate.platform.demo.store.CustomerCassandraStore;
import com.suntecgroup.xelerate.platform.demo.store.impl.CustomerCassandraStoreImpl;
#Table(value="CustomerCassandra")
public class CustomerCassandra extends CassandraEntity<Integer> {
#PrimaryKey(value="cust_id")
private Integer custId;
#Indexed(value="name")
private String name;
#Indexed(value="email")
private String email;
#Column(value="domain")
private String domain;
#Column(value="category")
private String category;
#Column(value="created_at")
private Date createdAt;
#CassandraType(type=DataType.Name.LIST,typeArguments = { DataType.Name.UDT }, userTypeName = "address_demo_type")
#Column(value="addresses")
private List<Address> addresses;
#Override
public Integer getId() {
return custId;
}
#Override
public void setId(Integer id) {
this.custId = id;
}
public static CustomerCassandraStore getStore() {
return (CustomerCassandraStore) SpringContainer.getBean(CustomerCassandraStoreImpl.class);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public List<Address> getAddresses() {
return addresses;
}
public void setAddresses(Address... addresses) {
LinkedList<Address> addressList = new LinkedList<>();
for(Address addr: addresses) {
addressList.add(addr);
}
setAddresses(addressList);
}
public void setAddresses(List<Address> addresses) {
this.addresses = addresses;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
#UserDefinedType(value="address_demo_type")
public static class Address {
#CassandraType(type = DataType.Name.TEXT)
#Column(value="street_address")
private String streetAddress;
#CassandraType(type = DataType.Name.TEXT)
#Column(value="city")
private String city;
#CassandraType(type = DataType.Name.TEXT)
#Column(value="country")
private String country;
#CassandraType(type = DataType.Name.TEXT)
#Column(value="pincode")
private String pincode;
public String getStreetAddress() {
return streetAddress;
}
public void setStreetAddress(String streetAddress) {
this.streetAddress = streetAddress;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getPincode() {
return pincode;
}
public void setPincode(String pincode) {
this.pincode = pincode;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((city == null) ? 0 : city.hashCode());
result = prime * result + ((country == null) ? 0 : country.hashCode());
result = prime * result + ((pincode == null) ? 0 : pincode.hashCode());
result = prime * result
+ ((streetAddress == null) ? 0 : streetAddress.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Address other = (Address) obj;
if (city == null) {
if (other.city != null)
return false;
} else if (!city.equals(other.city))
return false;
if (country == null) {
if (other.country != null)
return false;
} else if (!country.equals(other.country))
return false;
if (pincode == null) {
if (other.pincode != null)
return false;
} else if (!pincode.equals(other.pincode))
return false;
if (streetAddress == null) {
if (other.streetAddress != null)
return false;
} else if (!streetAddress.equals(other.streetAddress))
return false;
return true;
}}
}
It looks like some bug in spring-data-cassandra lib. I'm not able to create index through annotation as well.
I faced a similar issue while creating the schema during test execution (it's not clear how the OP creates the table based on the annotations).
My code was invoking CassandraAdminOperations.createTable() function and I quickly found out that createTable does not include indices, so any queries on the (supposedly) indexed columns were failing. My original code was just:
#Autowired
private CassandraAdminOperations adminTemplate;
#Before
public void createTable() {
adminTemplate.createTable(true, CqlIdentifier.of(DATA_TABLE_NAME), User.class, new HashMap<>());
}
In order to generate the indices based on the annotations, I had to modify my #Before method as:
#Autowired
private CassandraAdminOperations adminTemplate;
#Before
public void createTable() {
adminTemplate.createTable(true, CqlIdentifier.of(DATA_TABLE_NAME), User.class, new HashMap<>());
CassandraPersistentEntity<?> entity = adminTemplate.getConverter().getMappingContext().getRequiredPersistentEntity(User.class);
List<CreateIndexSpecification> indexSpecifications = adminTemplate.getConverter().getMappingContext().getCreateIndexSpecificationsFor(entity);
indexSpecifications.forEach(is -> adminTemplate.getCqlOperations().execute((CreateIndexCqlGenerator.toCql(is))));
}
Table tableAnno=AnnotationUtils.getAnnotation(MessagePO.class, Table.class);
String tableName=tableAnno.value();
log.info("initial table{}",tableName);
/**
* create table
*/
adminTemplate.createTable(true, CqlIdentifier.fromCql(tableName), MessagePO.class, null);
Field[] fields = MessagePO.class.getDeclaredFields();
/**
* create index
*/
CqlOperations cqlOperations=adminTemplate.getCqlOperations();
Arrays.stream(fields).forEach(field -> {
Indexed indexed = AnnotationUtils.getAnnotation(field, Indexed.class);
Column column = AnnotationUtils.getAnnotation(field, Column.class);
if (indexed != null && column != null) {
String indexVal = indexed.value();
String indexSql=String.format("CREATE INDEX %s on %s(%s)",indexVal,tableName,column.value());
cqlOperations.execute(String.format("DROP INDEX if EXISTS %s",indexVal));
cqlOperations.execute(indexSql);
log.info("create index {}",indexSql);
}
});
this is my initial index code, it's work well

PK of #ManyToOne relation not inserted

I have an application (Spring 4 MVC+Hibernate 4+MySQL+Maven integration example using annotations) , integrating Spring with Hibernate using annotation based configuration.
I have this domain object:
#Entity
#Table(name="t_device")
public class Device {
enum Type {
IOS,
ANDROID
}
public Device() {
super();
}
public Device(String key) {
super();
this.key = key;
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#NotEmpty
#Size(min=1, max=50)
#Column(name = "device_key", unique=true, nullable = false)
private String key;
#Column(name = "device_desc")
private String desc;
#Enumerated(EnumType.STRING)
#Column(name = "device_type")
private Type type;
#OneToOne(fetch=FetchType.EAGER)
#JoinColumn(name = "application_id",
referencedColumnName = "id")
private Application application;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public Application getApplication() {
return application;
}
public void setApplication(Application application) {
this.application = application;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((desc == null) ? 0 : desc.hashCode());
result = prime * result + id;
result = prime * result + ((key == null) ? 0 : key.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Device other = (Device) obj;
if (desc == null) {
if (other.desc != null)
return false;
} else if (!desc.equals(other.desc))
return false;
if (id != other.id)
return false;
if (key == null) {
if (other.key != null)
return false;
} else if (!key.equals(other.key))
return false;
return true;
}
#Override
public String toString() {
return "Device [id=" + id + ", key=" + key + ", desc=" + desc + "]";
}
}
That is linked to this other one:
#Entity
#Table(name="t_device_event")
public class DeviceEvent {
public class Coordinates {
#Column(name = "device_lat")
private Double lat;
#Column(name = "device_lng")
private Double lng;
public Coordinates(Double lat, Double lng) {
super();
this.lat = lat;
this.lng = lng;
}
public Double getLat() {
return lat;
}
public void setLat(Double lat) {
this.lat = lat;
}
public Double getLng() {
return lng;
}
public void setLng(Double lng) {
this.lng = lng;
}
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#ManyToOne
private Device device;
private Long received;
private String message;
#Transient
private Coordinates coordinates;
public Coordinates getCoordinates() {
return coordinates;
}
public void setCoordinates(Coordinates coordinates) {
this.coordinates = coordinates;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Device getDevice() {
return device;
}
public void setDevice(Device device) {
this.device = device;
}
public Long getReceived() {
return received;
}
public void setReceived(Long received) {
this.received = received;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public DeviceEvent(Device device) {
super();
this.device = device;
}
}
and this piece of code in the controller:
Device device = deviceService.findByKey("AS3989E506");
DeviceEvent deviceEvent = new DeviceEvent(device);
deviceEvent.setCoordinates(deviceEvent.new Coordinates(Double.MIN_VALUE, Double.MAX_VALUE));
deviceEvent.setMessage("message");
deviceEvent.setReceived(new Date().getTime());
deviceEventService.save(deviceEvent);
and the hibernate console:
Hibernate:
select
this_.id as id1_1_1_,
this_.application_id as applicat5_1_1_,
this_.device_desc as device_d2_1_1_,
this_.device_key as device_k3_1_1_,
this_.device_type as device_t4_1_1_,
applicatio2_.id as id1_0_0_,
applicatio2_.application_desc as applicat2_0_0_,
applicatio2_.application_key as applicat3_0_0_
from
t_device this_
left outer join
t_application applicatio2_
on this_.application_id=applicatio2_.id
where
this_.device_key=?
Hibernate:
insert
into
t_device_event
(device_id, message, received)
values
(?, ?, ?)
Hibernate:
select
this_.id as id1_1_1_,
this_.application_id as applicat5_1_1_,
this_.device_desc as device_d2_1_1_,
this_.device_key as device_k3_1_1_,
this_.device_type as device_t4_1_1_,
applicatio2_.id as id1_0_0_,
applicatio2_.application_desc as applicat2_0_0_,
applicatio2_.application_key as applicat3_0_0_
from
t_device this_
left outer join
t_application applicatio2_
on this_.application_id=applicatio2_.id
Here the services:
#Service("deviceEventService")
#Transactional
public class DeviceEventServiceImpl implements DeviceEventService {
#Autowired
private DeviceEventDao dao;
public void save(DeviceEvent deviceEvent) {
dao.save(deviceEvent);
}
}
the other:
#Service("deviceService")
#Transactional
public class DeviceServiceImpl implements DeviceService {
#Autowired
private DeviceDao dao;
public Device findById(int id) {
return dao.findById(id);
}
public void save(Device device) {
dao.save(device);
}
public void update(Device device) {
// TODO Auto-generated method stub
}
public void delete(Device device) {
// TODO Auto-generated method stub
}
public List<Device> findAll() {
return dao.findAll();
}
public Device findByKey(String key) {
return dao.findByKey(key);
}
public boolean isDeviceKeyUnique(Integer id, String key) {
Device device = findByKey(key);
return ( device == null || ((id != null) && (device.getId() == id)));
}
public void deleteByKey(String key) {
dao.deleteByKey (key);
}
}
But the field device_id of the table t_device_event is null !
May be #JoinColumn annotation will help you
#ManyToOne
#JoinColumn(name="device_id")
private Device device;

JPA query for one to one relation

I have an EJB application in where I am using Entity beans for database. I have to Entity beans having unidirectional one to one relation, JobPositionEntity and CandidateEntity.
Here is CandidateEntity
#Entity
public class CandidateEntity extends BaseEntity {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private Long meritNumber;
private String seatNumber;
private String candidateName;
private String gender;
public Long getMeritNumber() {
return meritNumber;
}
public void setMeritNumber(Long meritNumber) {
this.meritNumber = meritNumber;
}
public String getSeatNumber() {
return seatNumber;
}
public void setSeatNumber(String seatNumber) {
this.seatNumber = seatNumber;
}
public String getCandidateName() {
return candidateName;
}
public void setCandidateName(String candidateName) {
this.candidateName = candidateName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
#Override
public Long getId() {
return id;
}
#Override
public void setId(Long id) {
this.id = id;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof CandidateEntity)) {
return false;
}
CandidateEntity other = (CandidateEntity) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.nisheeth.config.ejb.entity.CandidateEntity[ id=" + id + " ]";
}
}
Here is JobPositionEntity
#Entity
public class JobPositionEntity extends BaseEntity {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
#OneToOne(fetch = FetchType.EAGER, orphanRemoval = true, cascade = CascadeType.ALL)
private CandidateEntity candidate;
#ManyToOne(fetch = FetchType.EAGER)
private SeasonEntity season;
public SeasonEntity getSeason() {
return season;
}
public void setSeason(SeasonEntity season) {
this.season = season;
}
public CandidateEntity getCandidate() {
return candidate;
}
public void setCandidate(CandidateEntity candidate) {
this.candidate = candidate;
}
#Override
public Long getId() {
return id;
}
#Override
public void setId(Long id) {
this.id = id;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof JobPositionEntity)) {
return false;
}
JobPositionEntity other = (JobPositionEntity) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "com.nisheeth.config.ejb.entity.JobPositionEntity[ id=" + id + " ]";
}
}
I want to select candidates which are not in JobPositionEntity. I have this query which did not work for me:
select ce.candidateName, ce.id from JobPositionEntity jp left join jp.candidate ce where ce <> null
Can anyone help write this query? Thanks in advance.
you can use a SubQuery
select c from Candidate c where c.id not in
(select jp.candidate.id from JobPositionEntity jp)
for more information:
https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html#queryhql-subqueries

JPA cannot fill entries in join table

I'm trying to map a bidirectional ManyToMany relationship between the class Problem and the class Domain. Therefore the persistency unit creates a join table in the database, but it seems no entry pops up in the database.
Here's some code:
The class Problem
package domain;
import java.io.Serializable;
import java.util.List;
import javax.persistence.*;
import static javax.persistence.GenerationType.SEQUENCE;
import javax.xml.bind.annotation.XmlRootElement;
#Entity
#XmlRootElement
public class Problem implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private User user;
private String description;
private int maxprice;
private int priority;
private Solution solution;
private Location location;
private List<Domain> domains;
#Id
//#GeneratedValue(strategy = GenerationType.AUTO)
#SequenceGenerator(name="User_Seq", allocationSize=25)
#GeneratedValue(strategy=SEQUENCE, generator="Problem_Seq")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#ManyToOne
//#JoinColumn(name="user_id")
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getMaxPrice() {
return maxprice;
}
public void setMaxPrice(int maxprice) {
this.maxprice = maxprice;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name="solution_id")
public Solution getSolution() {
return solution;
}
public void setSolution(Solution solution) {
this.solution = solution;
}
#ManyToOne
#JoinColumn(name="location_id")
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
#ManyToMany
#JoinTable(name="problem_domain",
joinColumns={#JoinColumn(name="problem_id", referencedColumnName="ID")},
inverseJoinColumns={#JoinColumn(name="domain_id", referencedColumnName="ID")})
public List<Domain> getDomains() {
return domains;
}
public void setDomains(List<Domain> domains) {
this.domains = domains;
}
public void addDomain(Domain domain){
//this.domains.add(domain); //Throws NullpointerException om een of andere reden.
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Problem)) {
return false;
}
Problem other = (Problem) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "domain.Problem[ id=" + id + " ]";
}
}
The class Domain
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package domain;
import java.io.Serializable;
import java.util.List;
import javax.persistence.*;
import static javax.persistence.GenerationType.SEQUENCE;
import javax.xml.bind.annotation.XmlRootElement;
#Entity
#XmlRootElement
public class Domain implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String name;
private List<Problem> problems;
private List<Domain> subDomains;
private Domain superDomain;
#Id
#SequenceGenerator(name="Dom_Seq", allocationSize=25)
#GeneratedValue(strategy=SEQUENCE, generator="Dom_Seq")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#ManyToMany(mappedBy = "domains")
public List<Problem> getProblems() {
return problems;
}
public void setProblems(List<Problem> problems) {
this.problems = problems;
}
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
#JoinColumn(name="superdomain_id")
public List<Domain> getSubDomains() {
return subDomains;
}
public void setSubDomains(List<Domain> subDomains) {
this.subDomains = subDomains;
}
public Domain getSuperDomain() {
return superDomain;
}
public void setSuperDomain(Domain superDomain) {
this.superDomain = superDomain;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Domain)) {
return false;
}
Domain other = (Domain) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "domain.Domain[ id=" + id + " ]";
}
}
the code where we add a problem and a domain to the database
Problem problem = new Problem();
Domain domain = new Domain();
domain.setName(domainString);
domainFacade.create(domain);
problemFacade.create(problem);
problem.addDomain(domain);
problemFacade.edit(problem);
and a little visual explanation of the DB
Do you try to save List of domain to problem?
Example of code:
Problem problem = new Problem();
Domain domain = new Domain();
domain.setName(domainString);
domainFacade.create(domain);
List<Domain> domains = new ArrayList<Domain>();
domains.add(domain);
problem.setDomains(domains);
problemFacade.create(problem);
As #Neil Stockton and others said, the answer to my problem was that I had to have an addMethod that simply added the object to the list.

Categories