So I seem to be plagued by issues that only affect production mode in Symfony and not developer mode. This time, I have a ManyToOne association and I'm trying to fetch only the entities which do not have an association (i.e. they have a NULL value in the database). This works exactly as I'd expect in dev move, but in prod mode, Doctrine throws an "unrecognized field" exception... for a field which absolutely does exist.
Here's the relevant part of the entity in question (Page.php):
/**
* #ORM\ManyToOne(targetEntity="Project", inversedBy="pages")
* #ORM\JoinColumn(name="project_id", referencedColumnName="ID")
*/
protected $project;
And here is the relevant line from the controller (PageController.php):
$pages = $this->getDoctrine()->getRepository('JCScopingBundle:Page')->findBy(['project' => null]);
Again, this works perfectly using app_dev.php (i.e. dev mode), but using app.php (i.e. prod mode) I keep getting the "unrecognized field" exception. What gives?
Update: I added a "weight" integer field to the same entity and that field is not recognized in prod mode either. This means I can't use prod mode, which means I can't upload my changes to the remote server. Really in a pickle here...
Well, low and behold, restarting the Apache service resolved the issue. Apparently that's the only way to truly clear the APCu metadata cache. I was inspired to try this based on this question/answer: Doctrine mapped field is not working
In my case I forgot to restart 'memcached' service.
Check metadata_cache_driver type. In my case:
doctrine:
orm:
metadata_cache_driver:
type: memcached
host: localhost
port: 11211
instance_class: Memcached
Because previous metadata was cached, after applying migration, doctrine used that old cached metadata, without knowing about added new field.
Related
This is similar to Symfony3 You have requested a non-existent service "validator.builder", while add FOSUserBundle, on vanilla Symfon3.3 instead of microkernel (in case that makes differences).
Problem:
I have a problem trying to set up FOSUser (v.2) on a Symfony 3.3:
[Symfony\Component\DependencyInjection\Exception\AutowiringFailedException]
Cannot autowire service "validator.builder": argument "$node" of method
"Symfony\Component\Config\Definition\Builder\ValidationBuilder::__construct()"
references class Symfony\Component\Config\Definition\Builder\NodeDefinition"
but no such service exists.
Browsing through online API:
ValidationBuilder is marked up to the 3.2 branch, although exists in github
NodeDefinition is also marked up to v3.2, although exists in github
Does that mean that their documentation is not up to date with the master 3.3?
Or not maintained anymore?
Context:
Following the official documentation, I first faced these problems:
mailer_user cannot be null ; solved by editing parameters.yml:
parameters:
mailer_user: "me#example.com"
non-existent-service-validator-builder ; solved by declaring service validator.builder
non existent parameter kernel secret ; solved by duplicating a line in parameters.yml:
parameters:
secret: <-generated-upon-install->
kernel.secret: <-duplicated-line->
I suppose there is a nice and clever way to get out of this problem, if anyone faced it yet?
Solved! In service.yml, do not declare service as
validator.builder:
class: Symfony\Component\Config\Definition\Builder\ValidationBuilder
But this way:
Symfony\Component\Config\Definition\Builder\ValidationBuilder:
autowire: true
Once again, the official documentation had the answer!
Getting this exception in Symfony 2.5.5 with Swiftmailer 5.3.0. I'm following the cookbook example exactly. The error is thrown when calling MessageDataCollector#getMessages():
// Check that an e-mail was sent
$this->assertEquals(1, $mailCollector->getMessageCount());
$collectedMessages = $mailCollector->getMessages();
$message = $collectedMessages[0];
The message count assertion is also failing with a value of zero.
As far as I can tell the collector is failing to do any actual collecting in the action. Any ideas?
I encountered the same problem after I applied kriswallsmith's test optimization trick. I could see the result of the mail sending in the web profiler when running the development version, but couldn't get the data in the testing environment.
After applying Kris' trick I noticed that the swiftmailer.mailer.default.plugin.messagelogger service was not registered with the container during the test, so the collect() method of the MessageDataCollector class did not log the data for the mail sending. This is why it wasn't possible to retrieve information from the swiftmailer collector.
The solution is either not to overrride the initializeContainer() method in AppKernel.php or to override it, but making sure messagelogger service is available for test cases that send mails.
#codeBetyar is right - problem occurs when swiftmailer.mailer.default.plugin.messagelogger is not registered in container.
But instead of getting rid of the optimization trick - you just need to update swiftmailer configuration for test environment
swiftmailer:
logging: true
The thing is logging config value by default equals to kernel.debug (https://github.com/symfony/swiftmailer-bundle/blob/master/DependencyInjection/Configuration.php#L121) which (thanks to the trick) is true for the first test request, and false - for all following requests.
Above config forces logger being registered.
In my case I had multiple mailers in the config.yml file and the same problem was due to a missing parameter in the getMessages() call.
My config.yml file:
swiftmailer:
default_mailer: default_mailer
mailers:
default_mailer:
# some configuration
another_mailer:
# some configuration
The correct call was:
$mailCollector = $this->client->getProfile()->getCollector('swiftmailer');
$collectedMessages = $mailCollector->getMessages('default_mailer'); // please note the 'default_mailer' argument
$messagesCount = $mailCollector->getMessageCount('default_mailer')
My problem was that apparently if there are no messages to retrieve (or perhaps no swiftmailer instantiation in the code being tested?), the call to getMessages() returns this obtuse error. So I bypassed the problem by testing for getMessageCount() first.
I am trying to define a Bundle that helps to index some data (from an Entity) within a sqlite fts table, in order to do some full-text search.
I know I can define alternate connection and Entity Manager using the app config file (like shown in the cookbook), but I was wondering if it was possible to do so within the bundle configuration - by defining, for example, a service with the doctrine service injected, so that it can instantiate a new connection.
Sqlite is not mandatory, it can be any database type (supported by doctrine).
Thanks in advance for your help.
I would suggest looking at FOSUserBundle for how they handle multiple persistence layers (ORM, Couch, MongoDB). You would essentially be doing the same thing. It's just a matter of loading different configurations depending on the driver specified in app/config/config.yml.
As far as i know it it not possible. Also database connections should be managed centralized in app/config.yml.
I would suggest to define the connection there and add a configuration option to you bundle where you can specify wich connection to use for the indexing stuff.
# app/config.yml
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: database
host: localhost
user: user
password: secret
driver: pdo_mysql
my_data_index:
dbname: database
driver: pdo_sqlite
# configuration option of you bundle
acme_indexer:
connection: my_data_index
Then in your bundle you can read this config option and obtain the connection/entity manager and inject it into your indexing service.
Edit:
You can for sure create a custom connection programaticly in your bundle
$params = array(
'driver' =>'pdo_sqlite',
....
);
$factory = $container->get('doctrine.dbal.connection_factory')
$connection = $factory->createConnection($params);
But as i said before it is bad practice because you would evade the symfony standart way of defining database connections.
When testing my Tridion content delivery web service using a web browser, I can successfully get a list of the available collections by invoking "http://webservice/odata.svc/", however when I try to access one of the collections, for example;
http://webservice/odata.svc/Publications
I get;
<message xml:lang="en-US">Unable to retrieve desired results.</message>
or a specific item
http://webservice/odata.svc/Publications(19)
I get:
<message xml:lang="en-US">Unable to build publication entry:
Unable to retrieve desired results.</message>
In the logs I get the following (I've removed timestamps etc. to make it a bit more readable):
ODataService - ODATA.NET: Resource retrieval: Publications
WebContext - setCurrentClaimStore: com.tridion.ambientdata.dotnet.DotNetClaimStore#576504fa, thread: Thread-5
ODataWebserviceHandler - Requested a OData feed/entry: Publications with type: application/atom+xml
ODataWebserviceHandler - Setting $top to 25
ResolverBase - Requested OData collection
StorageManagerFactory - Loading a non cached DAO for publicationId/typeMapping/itemExtension: 0 / Query / null
JPQLExecutor - Can not create JPAQueryDAO object
com.tridion.broker.StorageException: No Data Access Object for Query
at com.tridion.storage.filesystem.FSDAOFactory.getDAOForTypeMapping(FSDAOFactory.java:177) ~[cd_datalayer.jar:na]
at com.tridion.storage.StorageManagerFactory.getOriginalDAO(StorageManagerFactory.java:450) ~[cd_datalayer.jar:na]
at com.tridion.storage.StorageManagerFactory.getDAO(StorageManagerFactory.java:271) ~[cd_datalayer.jar:na]
at com.tridion.storage.StorageManagerFactory.getDefaultDAO(StorageManagerFactory.java:178) ~[cd_datalayer.jar:na]
at com.tridion.webservices.odata.input.jpql.JPQLExecutor.<init>(JPQLExecutor.java:61) [cd_webservice.jar:na]
at com.tridion.webservices.odata.input.jpql.JPQLExecutor.getExecutor(JPQLExecutor.java:103) [cd_webservice.jar:na]
at com.tridion.webservices.odata.input.resolver.PublicationsResolver.resolveCollection(PublicationsResolver.java:34) [cd_webservice.jar:na]
at com.tridion.webservices.odata.input.resolver.ResolverBase.resolve(ResolverBase.java:74) [cd_webservice.jar:na]
at com.tridion.webservices.odata.input.handler.ODataFeedRenderer.renderODataFeed(ODataFeedRenderer.java:45) [cd_webservice.jar:na]
at com.tridion.webservices.odata.input.handler.ODataWebserviceHandler.handleODataEntity(ODataWebserviceHandler.java:193) [cd_webservice.jar:na]
at com.tridion.webservices.odata.input.handler.ODataWebserviceHandler.handleResourceRequest(ODataWebserviceHandler.java:169) [cd_webservice.jar:na]
FilterValue - check if value: 25 is of Integer type
FilterValue - value: 25 is Integer
JPQLExecutor - JPAQueryDAO has not been instantiated. Probably FS storage type was used.
ResolverBase - Unable to build feed Unable to retrieve desired results.
This message points at my storage configuration, however I have not been able to find any clear guidance in the documentation as to how it should be set up to support the web service.
How should my storage be configured? Is it normal to expect to have a separate deployer for the service and the web site? What other issues should I be considering?
The CD Webservice requires all your content to be in the CD DB. This means nothing on the file system. If you still have stuff on the FS, some parts of the CD Webservice will not work. For example, think about pages that might be on the FS -- you will not be able to retrieve the PageContent via the CD Webservice.
To your problem, check that your CD Webservice cd_storage_conf.xml defines a database (JPA) connection. And of course it is functional. Check the usual suspects, db connection, user, pass, url, JARs...
Edit: Taking a closer look at your stack trace, you must have defined the FS as default storage medium (due to getOriginalDAO(...), yielding a FSDAOFactory.getDAOForTypeMapping(...)). So I think this is the root of the problem. Check also that your license is valid, and that your 'bindings' have not reverted to FS due to missing/expired CD license.
As additional input for others, I was also experiencing the 'Unable to retrieve desired results.' response, and in my case it was due to my cd_licenses.xml not being in the bin/config directory, with the other configuration files.
I have the following scenario's:
#wip
Scenario: Attempt to get account information of an activator without credentials
Given an activator with e-mail "dietervds#email.com" and password "testpassword" already exists
When I send a GET request to "/activators/1"
Then the response code should be 401
#wip
Scenario: Attempt to get account information of another activator then myself
Given an activator with e-mail "dietervds#email.com" and password "testpassword" already exists
And an activator with e-mail "eviltwin#email.com" and password "testpassword" already exists
And I am authenticating as "eviltwin#email.com" with "testpassword" password
When I send a GET request to "/activators/1"
Then the response code should be 401
The database is dropped and re-created from schema before every scenario.
The step 'given an activator with ...' inserts a new user into the database.
However! It doesn't always do that for both users.
This is the step implementation:
/**
* #Given /^an activator with e-mail "([^"]*)" and password "([^"]*)" already exists$/
*/
public function anActivatorWithEMailAndPasswordAlreadyExists($email, $password)
{
$activatorManager = $this->getContainer()->get('am.manager.activator');
#$logger = $this->getContainer()->get('logger');
#$logger->debug("Email: $email, password: $password");
$activator = $activatorManager->createActivator($email, $password);
$activatorManager->save($activator);
}
Now the weird thing:
In that last step, I should be getting two inserts: one for dietervds, one of eviltwin.
I get the two inserts when I:
Run only one scenario
Output something in logging (creating the 'logger' doesn't help, I need to output something. What I output doesn't have to be dynamic, it can just be a fixed string)
I only get one insert (for dietervds) when I:
Run the two scenarios together
Or when I don't output any logging in the step implementation
I am completely baffled by this.
Is there something obvious that's missing? Might it be some sort of caching problem in the step definitions? (the logging might change the signature or something, not sure)
Any feedback is welcome :-)
Cheers!
Dieter
Does this step def do an ajax call?
When I send a GET request to "/activators/1"
if it does you could try adding some wait time in there to give your dom time to load the result
Whens to Thens work best when you are submitting forms with press or following links or doing go to's to redirect the browser which initiates a full request response cycle that triggers the robot to wait for a new dom to load.
With ajax that doesn't happen exactly the same way.
If you aren't doing ajax I recommend you just use the built in step defs of
When I follow "/activators/1" instead
There is a way to prevent caching in your yaml config. Here is an example config we use for chrome but it should work the same for any browser driver
default:
extensions:
Behat\MinkExtension\Extension:
base_url: https://yurwebsite.com
goutte: ~
browser_name: "googlechrome"
selenium2:
capabilities: { "browser": "googlechrome", "version": "23", "applicationCacheEnabled": false }
The last boolean param does the trick for our browser caching issues