This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I have model as follow
/**
* #Id
* #Column(type="integer",nullable=false)
* #generatedValue(strategy="AUTO")
*/
private $id;
/**
* #Column(type="string",nullable=false,unique=true)
*/
private $email;
/**
* #Column(type="string",length=64,nullable=false)
*/
private $password;
/**
* #Column(type="string",nullable=false)
*/
private $first_name;
/**
* #Coulmn(type="string",nullable=false)
*/
private $last_name;
When I run
orm:schema-tool:create
it generate the table on the database with all fields except Last_name ?
Seems like you have a typo: #Coulmn(type="string",nullable=false) should be #Column(type="string",nullable=false)
Related
In my Spring Boot application generated with JHipster (v6.0.1) Kotlin blueprint (v0.8.0) I have the following POST request handler
#PostMapping("/book")
fun createBook(#RequestBody createBookVM: CreateBookVM): ResponseEntity<Book> {
val author = authorRepository.getOne(createBookVM.authorId)
val userLogin = SecurityUtils.getCurrentUserLogin().orElseThrow { RuntimeException("User not logged in") }
val user = userRepository.findOneByLogin(userLogin).orElseThrow { RuntimeException("IMPOSSIBLE: user does not exist in DB") }
val book= Book()
book.author = author // FIXME
book.user = user
log.debug("Author object with id : {}", author.id) // THIS WORKS
val result = bookRepository.save(book)
return ResponseEntity.created(URI("/api/books/" + result.id))
.headers(HeaderUtil.createEntityCreationAlert(applicationName, true, ENTITY_NAME, result.id.toString()))
.body(result)
}
The problem is that the author is not added to the book (book.author will be null). However, I can access the values of author as shown with the logging statement. Adding user to book also works fine.
I suppose the problem is that authorRepository.getOne(createBookVM.authorId) returns a proxy object, not an instance of Author, but I do not know how to cope with this situation.
Instead of using authorRepository.getOne(createBookVM.binId) use authorRepository.findById(createBookVM.binId).
T getOne(ID id) returns a reference, not an entity.
/**
* Returns a reference to the entity with the given identifier.
*
* #param id must not be {#literal null}.
* #return a reference to the entity with the given identifier.
* #see EntityManager#getReference(Class, Object)
* #throws javax.persistence.EntityNotFoundException if no entity exists for given {#code id}.
*/
T getOne(ID id);
Optional<T> findById(ID id) returns an entity.
/**
* Retrieves an entity by its id.
*
* #param id must not be {#literal null}.
* #return the entity with the given id or {#literal Optional#empty()} if none found
* #throws IllegalArgumentException if {#code id} is {#literal null}.
*/
Optional<T> findById(ID id);
Also you can use authorRepository.findOne(createBookVM.binId) for older versions than jpa 2.x.x :
/**
* Retrieves an entity by its id.
*
* #param id must not be {#literal null}.
* #return the entity with the given id or {#literal null} if none found
* #throws IllegalArgumentException if {#code id} is {#literal null}
*/
T findOne(ID id);
Hello I am using Cassandra to save user data . I want to store data of a user for only 24 hours so I am giving a ttl for 24 hours. For each user there are multiple entries. So I want to batch insert data for each user instead of multiple calls to data base . I am using Cassandra operations to give ttl . I am able to give ttl for single record . How to provide ttl when inserting data in batches
public class CustomizedUserFeedRepositoryImpl<T> implements CustomizedUserFeedRepository<T> {
private CassandraOperations cassandraOperations;
#Autowired
CustomizedUserFeedRepositoryImpl(CassandraOperations cassandraOperations){
this.cassandraOperations = cassandraOperations;
}
#Override
public <S extends T> S save(S entity, int ttl){
InsertOptions insertOptions;
if(ttl == 0) {
insertOptions = InsertOptions.builder().ttl(Duration.ofHours(24)).build();
} else {
insertOptions = InsertOptions.builder().ttl(ttl).build();
}
cassandraOperations.insert(entity,insertOptions);
return entity;
}
#Override
public void saveAllWithTtl(java.lang.Iterable<T> entities, int ttl){
entities.forEach(entity->{
save(entity,ttl);
});
}
}
As you can see I have to iterate over the list make and make database calls for each record . The batch operation cassandraOperations.batchOps().insert() only takes list of objects . How to set ttl for each record when using batchops() fucntion ?
/**
* Add a collection of inserts with given {#link WriteOptions} to the batch.
*
* #param entities the entities to insert; must not be {#literal null}.
* #param options the WriteOptions to apply; must not be {#literal null}.
* #return {#code this} {#link CassandraBatchOperations}.
* #throws IllegalStateException if the batch was already executed.
* #since 2.0
*/
CassandraBatchOperations insert(Iterable<?> entities, WriteOptions options);
You can use insert(Iterable<?> entities, WriteOptions options) method
#EqualsAndHashCode(callSuper = true)
public class WriteOptions extends QueryOptions {
private static final WriteOptions EMPTY = new WriteOptionsBuilder().build();
private final Duration ttl;
private final #Nullable Long timestamp;
batchOperations.insert(entity, WriteOptions.builder().ttl(20).build());
I'm using Doctrine ORM for my project and I have an issue with my tables :
device (id, name, ip_address)
device_group (id, name)
template (id, object_type, object_id)
So these three entities extend from a superclass for common fields such as ID, timestamp...
If we take a look at the template entity, the object_id field refers either to device.id or device_group.id, depending on the value of object_type (a string that can be 'device' or 'group'). I would like to know how to make a relationship that has multiple targets, if possible.
Device_group :
/**
* #ORM\Entity(repositoryClass="App\Doctrine\Repositories\DeviceGroup")
* #ORM\Table(name="device_group")
*/
class DeviceGroup extends BaseModel
{
/**
* #ORM\Column(type="string", name="name", length=255)
*/
protected $name;
}
Device
/**
* #ORM\Entity(repositoryClass="App\Doctrine\Repositories\Device")
* #ORM\Table(name="device")
*/
class Device extends BaseModel
{
/**
* #ORM\Column(type="string", name="name", length=255)
*/
protected $name;
/**
* #ORM\Column(type="string", name="ip_address", length=45)
*/
protected $ip_address;
}
Template
**
* #ORM\Entity(repositoryClass="App\Doctrine\Repositories\Template")
* #ORM\Table(name="template")
*/
class DevicePart extends BaseModel
{
/**
* #ORM\Column(type="string", name="object_type", length=6)
*/
protected $object_type;//can be 'group' or 'device'
/**
* Many DevicePart have one Object
* #ORM\ManyToOne(targetEntity="?????????")
* #ORM\JoinColumn(name="object_id", referencedColumnName="id")
*/
protected $objects;
//target entity can be : App\Doctrine\Entities\Device" or "App\Doctrine\Entities\DeviceGroup
}
I heard about inheritance mapping and I already implement that with my superclass, I looked at some examples but that would make me create new tables, the thing is I have to keep the current structure as the data are used by other programs (SQL Alchemy with Python scripts).
Do you have any idea ?
Thanking you in advance,
I have a one-to-many relationship in Product and Product_Order. I want to use cascade such that on deleting Product record from Product it does not delete already saved record from Product_Order, but just make them orphan in child table. What should I use and how?
public class Product implements Serializable {
#OneToMany(mappedBy="product")
private Set<ProductOrder> productOrder;
Below code snippet form hibernate CascadeType class.
Option All includes all the below operations.
As you can clearly see, DELETE corresponds to Hibernate and not JPA, so JPA uses (orphanRemoval=true) option to delete child record.
From Hibernate
public enum CascadeType {
/**
* Includes all types listed here.
*/
ALL,
/**
* Corresponds to {#link javax.persistence.CascadeType#PERSIST}.
*/
PERSIST,
/**
* Corresponds to {#link javax.persistence.CascadeType#MERGE}.
*/
MERGE,
/**
* Corresponds to {#link javax.persistence.CascadeType#REMOVE}.
*/
REMOVE,
/**
* Corresponds to {#link javax.persistence.CascadeType#REFRESH}.
*/
REFRESH,
/**
* Corresponds to the Hibernate native DELETE action.
*/
DELETE,
/**
* Corresponds to the Hibernate native SAVE_UPDATE (direct reattachment) action.
*/
SAVE_UPDATE,
/**
* Corresponds to the Hibernate native REPLICATE action.
*/
REPLICATE,
/**
* Hibernate originally handled orphan removal as a specialized cascade.
*
* #deprecated use #OneToOne(orphanRemoval=true) or #OneToMany(orphanRemoval=true)
*/
#Deprecated
DELETE_ORPHAN,
/**
* Corresponds to the Hibernate native LOCK action.
*/
LOCK,
/**
* JPA originally planned on calling DETACH EVICT.
*
* #deprecated use javax.persistence.CascadeType.DETACH
*/
#Deprecated
EVICT,
/**
* Corresponds to {#link javax.persistence.CascadeType#REFRESH}.
*/
DETACH
}
From JPA
public enum CascadeType {
/** Cascade all operations */
ALL,
/** Cascade persist operation */
PERSIST,
/** Cascade merge operation */
MERGE,
/** Cascade remove operation */
REMOVE,
/** Cascade refresh operation */
REFRESH,
/**
* Cascade detach operation
*
* #since Java Persistence 2.0
*
*/
DETACH
}
Hope now things should be much clear
In your delete() of your ProductDao class, you will need to get the productOrder set, iterate through each order, set each order's product to null, update it in database. Something like this:
for (ProductOrder order : product.getProductOrder())
{
order.setProduct(null);
ProductOrderDao.update(order);
}
session.delete(product);
This may work, but I don't recommend this. Leaving orphan objects in your database will probably make it messy and therefore hard to manage in future.
i'm building a Q&A site and my questions, answers and comments are on the same posts table. But their postType is different. I can get answers for a question and comments for an answer with this association:
/**
* #OneToMany(targetEntity="Cms\Entity\Post", mappedBy="parent")
*/
private $answers;
/**
* #OneToMany(targetEntity="Cms\Entity\Post", mappedBy="parent")
*/
private $comments;
But i think this is not the correct way to do this because if i fetch a question both answers and comments are filling with just answers. I have to set a condition for relation like postType = 1
How can i do this?
Your schema is invalid. You schould have two different objects for answers and comments as they are two different things, even if they share a common interface.
You should create two entities, Answer and Comment and create assocations to them. As they are almost the same thing you could create an abstract class, AbstractContent, that defines all required fields and accessor methods. Doctrine supports inheritance so the final database schema will be exactly the same, but your OO model will be correct.
/**
* #MappedSuperclass
* #InheritanceType("SINGLE_TABLE")
* #DiscriminatorColumn(type = "string", name = "discriminator")
* #DiscriminatorMap({ "answer" = "Answer", "comment" = "Comment" })
*/
abstract class AbstractContent {
/** #Column(type = "integer") #Id #GeneratedValue("AUTO") */
protected $id;
/** #Column(type="text") */
protected $content;
/** #Column(type = "datetime", name = "created_at") */
protected $createdAt;
public function __construct() {
$this->createdAt = new \DateTime();
}
}
/** #Entity */
class Answer extends AbstractContent { }
/** #Entity */
class Comment extends AbstractContent { }
/**
* #OneToMany(targetEntity="Cms\Entity\Answer", mappedBy="parent")
*/
private $answers;
/**
* #OneToMany(targetEntity="Cms\Entity\Comment", mappedBy="parent")
*/
private $comments;
You can read more about inheritance in Doctrine on its documentation pages: Inheritance Mapping
Use Doctrine's Filtering Collections Criteria class. You can even filter the collection first before the sql query:
If the collection has not been loaded from the database yet, the
filtering API can work on the SQL level to make optimized access to
large collections.
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
...
/** #var Collection */
protected $posts;
/**
* #return Post[]
*/
public function getAnswers()
{
$criteria = Criteria::create()
->where(Criteria::expr()->eq('postType', 'answer'))
;
return $this->posts->matching($criteria);
}
/**
* #return Post[]
*/
public function getComments()
{
$criteria = Criteria::create()
->where(Criteria::expr()->eq('postType', 'comment'))
;
return $this->posts->matching($criteria);
}